Add support for smackfs directory: /sys/fs/smackfs/
authorPassion,Zhao <passion.zhao@intel.com>
Mon, 5 Nov 2012 12:27:10 +0000 (20:27 +0800)
committerJarkko Sakkinen <jarkko.sakkinen@iki.fi>
Thu, 8 Nov 2012 07:13:31 +0000 (09:13 +0200)
Signed-off-by: Passion,Zhao <passion.zhao@intel.com>
Suggested-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
libsmack/Makefile.am
libsmack/dso.h [new file with mode: 0644]
libsmack/init.c [new file with mode: 0644]
libsmack/libsmack.c
libsmack/libsmack.sym
libsmack/sys/smack.h
utils/common.c
utils/common.h

index 4ee9c84..09d0778 100644 (file)
@@ -10,7 +10,7 @@ lib_LTLIBRARIES = libsmack.la
 libsmack_la_LDFLAGS = \
        -version-info 1:0:0 \
        -Wl,--version-script=$(top_srcdir)/libsmack/libsmack.sym
-libsmack_la_SOURCES = libsmack.c
+libsmack_la_SOURCES = libsmack.c init.c
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libsmack.pc
diff --git a/libsmack/dso.h b/libsmack/dso.h
new file mode 100644 (file)
index 0000000..88b9b72
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This file is part of libsmack. Derived from libselinux/src/dso.h.
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Authors:
+ * Passion Zhao <passion.zhao@intel.com>
+ */
+
+#ifndef _SMACK_DSO_H
+#define _SMACK_DSO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SHARED
+# define hidden __attribute__ ((visibility ("hidden")))
+# define hidden_proto(fct) __hidden_proto (fct, fct##_internal)
+# define __hidden_proto(fct, internal) \
+     extern __typeof (fct) internal;   \
+     extern __typeof (fct) fct __asm (#internal) hidden;
+# if defined(__alpha__) || defined(__mips__)
+#  define hidden_def(fct) \
+     asm (".globl " #fct "\n" #fct " = " #fct "_internal");
+# else
+#  define hidden_def(fct) \
+     asm (".globl " #fct "\n.set " #fct ", " #fct "_internal");
+#endif
+#else
+# define hidden
+# define hidden_proto(fct)
+# define hidden_def(fct)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libsmack/init.c b/libsmack/init.c
new file mode 100644 (file)
index 0000000..d12f445
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * This file is part of libsmack. Derived from libselinux/src/init.c.
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Authors:
+ * Passion Zhao <passion.zhao@intel.com>
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <dlfcn.h>
+#include <sys/statvfs.h>
+#include <sys/vfs.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include "dso.h"
+
+/*
+ *  * smackfs magic number
+ *   */
+#define SMACK_MAGIC     0x43415d53 /* "SMAC" */
+
+/* smack file system type */
+#define SMACKFS "smackfs"
+
+#define SMACKFSMNT "/sys/fs/smackfs/"
+#define OLDSMACKFSMNT "/smack"
+
+static char *smack_mnt = NULL;
+
+void set_smackmnt(const char *mnt)
+{
+       smack_mnt = strdup(mnt);
+}
+
+hidden_def(set_smackmnt)
+
+
+/* Verify the mount point for smack file system has a smackfs.
+ * If the file system:
+ * Exist,
+ * Is mounted with an smack file system,
+ * The file system is read/write
+ * then set this as the default file system.
+ */
+static int verify_smackmnt(const char *mnt)
+{
+       struct statfs sfbuf;
+       int rc;
+
+       do {
+               rc = statfs(mnt, &sfbuf);
+       } while (rc < 0 && errno == EINTR);
+
+       if (rc == 0) {
+               if ((uint32_t)sfbuf.f_type == (uint32_t)SMACK_MAGIC) {
+                       struct statvfs vfsbuf;
+                       rc = statvfs(mnt, &vfsbuf);
+                       if (rc == 0) {
+                               if (!(vfsbuf.f_flag & ST_RDONLY)) {
+                                       set_smackmnt(mnt);
+                               }
+                               return 0;
+                       }
+               }
+       }
+
+       return -1;
+}
+
+int smackfs_exists(void)
+{
+       int exists = 0;
+       FILE *fp = NULL;
+       char *buf = NULL;
+       size_t len;
+       ssize_t num;
+
+       fp = fopen("/proc/filesystems", "r");
+       if (!fp)
+               return 1; /* Fail as if it exists */
+
+       __fsetlocking(fp, FSETLOCKING_BYCALLER);
+
+       num = getline(&buf, &len, fp);
+       while (num != -1) {
+               if (strstr(buf, SMACKFS)) {
+                       exists = 1;
+                       break;
+               }
+               num = getline(&buf, &len, fp);
+       }
+
+       free(buf);
+       fclose(fp);
+       return exists;
+}
+
+hidden_def(smackfs_exists)
+
+static void init_smackmnt(void)
+{
+       char *buf=NULL, *p;
+       FILE *fp=NULL;
+       size_t len;
+       ssize_t num;
+
+       if (smack_mnt)
+               return;
+
+       if (verify_smackmnt(SMACKFSMNT) == 0) 
+               return;
+
+       if (verify_smackmnt(OLDSMACKFSMNT) == 0) 
+               return;
+
+       /* Drop back to detecting it the long way. */
+       if (!smackfs_exists())
+               goto out;
+
+       /* At this point, the usual spot doesn't have an smackfs so
+        * we look around for it */
+       fp = fopen("/proc/mounts", "r");
+       if (!fp)
+               goto out;
+
+       __fsetlocking(fp, FSETLOCKING_BYCALLER);
+       while ((num = getline(&buf, &len, fp)) != -1) {
+               char *tmp;
+               p = strchr(buf, ' ');
+               if (!p)
+                       goto out;
+               p++;
+
+               tmp = strchr(p, ' ');
+               if (!tmp)
+                       goto out;
+
+               if (!strncmp(tmp + 1, SMACKFS" ", strlen(SMACKFS)+1)) {
+                       *tmp = '\0';
+                       break;
+               }
+       }
+
+       /* If we found something, dup it */
+       if (num > 0)
+               verify_smackmnt(p);
+
+      out:
+       free(buf);
+       if (fp)
+               fclose(fp);
+       return;
+}
+
+const char *smack_smackfs_path(void)
+{
+       return smack_mnt;
+}
+
+void fini_smackmnt(void)
+{
+       free(smack_mnt);
+       smack_mnt = NULL;
+}
+
+hidden_def(fini_smackmnt)
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+       init_smackmnt();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+       fini_smackmnt();
+}
index adcdf76..3d034da 100644 (file)
@@ -21,6 +21,7 @@
  * Authors:
  * Jarkko Sakkinen <jarkko.sakkinen@intel.com>
  * Brian McGillion <brian.mcgillion@intel.com>
+ * Passion Zhao <passion.zhao@intel.com>
  */
 
 #include "sys/smack.h"
@@ -33,6 +34,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <limits.h>
 
 #define LABEL_LEN 255
 #define ACC_LEN 5
 #define KERNEL_LONG_FORMAT "%s %s %s"
 #define KERNEL_SHORT_FORMAT "%-23s %-23s %5s"
 #define READ_BUF_SIZE LOAD_LEN + 1
-#define SMACKFS_MNT "/smack"
 #define SELF_LABEL_FILE "/proc/self/attr/current"
 
+const char *smack_mnt;
+
 struct smack_rule {
        char subject[LABEL_LEN + 1];
        char object[LABEL_LEN + 1];
@@ -242,20 +245,30 @@ int smack_have_access(const char *subject, const char *object,
        int ret;
        int fd;
        int access2 = 1;
+       char path[PATH_MAX];
 
-       access_code = access_type_to_int(access_type);
-       int_to_access_type_k(access_code, access_type_k);
-
-       fd = open(SMACKFS_MNT "/access2", O_RDWR);
+       smack_mnt = smack_smackfs_path();
+       if (!smack_mnt) {
+               errno = EFAULT;
+               return -1; 
+       }
+       
+       snprintf(path, sizeof path, "%s/access2", smack_mnt);
+       fd = open(path, O_RDWR);
        if (fd < 0) {
                if (errno != ENOENT)
                        return -1;
-               fd = open(SMACKFS_MNT "/access", O_RDWR);
+               
+               snprintf(path, sizeof path, "%s/access", smack_mnt);
+               fd = open(path, O_RDWR);
                if (fd < 0)
                        return -1;
                access2 = 0;
        }
 
+       access_code = access_type_to_int(access_type);
+       int_to_access_type_k(access_code, access_type_k);
+
        if (access2)
                ret = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
                               subject, object, access_type_k);
@@ -395,8 +408,16 @@ int smack_cipso_apply(struct smack_cipso *cipso)
        char buf[CIPSO_MAX_SIZE];
        int fd;
        int i;
+       char path[PATH_MAX];
 
-       fd = open(SMACKFS_MNT "/cipso2", O_WRONLY);
+       smack_mnt = smack_smackfs_path();
+       if (!smack_mnt) {
+               errno = EFAULT;
+               return -1; 
+       }
+       
+       snprintf(path, sizeof path, "%s/cipso2", smack_mnt);
+       fd = open(path, O_WRONLY);
        if (fd < 0)
                return -1;
 
@@ -455,7 +476,7 @@ int smack_new_label_from_socket(int fd, char **label)
        if (ret < 0 && errno != ERANGE)
                return -1;
 
-        result = calloc(length + 1, 1);
+       result = calloc(length + 1, 1);
        if (result == NULL)
                return -1;
 
@@ -477,13 +498,22 @@ static int accesses_apply(struct smack_accesses *handle, int clear)
        int ret;
        int fd;
        int load2 = 1;
+       char path[PATH_MAX];
 
-       fd = open(SMACKFS_MNT "/load2", O_WRONLY);
+       smack_mnt = smack_smackfs_path();
+       if (!smack_mnt) {
+               errno = EFAULT;
+               return -1; 
+       }
+       
+       snprintf(path, sizeof path, "%s/load2", smack_mnt);
+       fd = open(path, O_WRONLY);
        if (fd < 0) {
                if (errno != ENOENT)
                        return -1;
                /* fallback */
-               fd = open(SMACKFS_MNT "/load", O_WRONLY);
+               snprintf(path, sizeof path, "%s/load", smack_mnt);
+               fd = open(path, O_WRONLY);
                if (fd < 0)
                        return -1;
                load2 = 0;
index ed9da3c..f1b3cc1 100644 (file)
@@ -11,6 +11,7 @@ global:
         smack_cipso_free;
         smack_cipso_new;
         smack_cipso_apply;
+       smack_smackfs_path;
        smack_new_label_from_self;
        smack_new_label_from_socket;
 local:
index 28cce4e..ce0c0c1 100644 (file)
@@ -124,6 +124,11 @@ void smack_cipso_free(struct smack_cipso *cipso);
 int smack_cipso_apply(struct smack_cipso *cipso);
 
 /*!
+ * Get the smackfs directory.
+ */
+const char *smack_smackfs_path(void);
+
+/*!
   * Get the label that is associated with the callers process.
   * Caller is responsible of freeing the returned label.
   *
index afa33a4..2f51815 100644 (file)
@@ -34,8 +34,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 
-#define SMACKFS_MAGIC 0x43415d53
+#define SMACK_MAGIC 0x43415d53
 
 static int apply_rules_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
 static int apply_cipso_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf);
@@ -44,15 +45,22 @@ int is_smackfs_mounted(void)
 {
        struct statfs sfs;
        int ret;
+       const char * smack_mnt;
+
+       smack_mnt = smack_smackfs_path();
+       if (!smack_mnt) {
+               errno = EFAULT;
+               return -1;
+       }
 
        do {
-               ret = statfs(SMACKFS_MNT, &sfs);
+               ret = statfs(smack_mnt, &sfs);
        } while (ret < 0 && errno == EINTR);
 
        if (ret)
                return -1;
 
-       if (sfs.f_type == SMACKFS_MAGIC)
+       if (sfs.f_type == SMACK_MAGIC)
                return 1;
 
        return 0;
@@ -62,11 +70,20 @@ int clear(void)
 {
        int fd;
        int ret;
+       const char * smack_mnt;
+       char path[PATH_MAX];
+
+       smack_mnt = smack_smackfs_path();
+       if (!smack_mnt) {
+               errno = EFAULT;
+               return -1;
+       }
 
        if (is_smackfs_mounted() != 1)
                return -1;
 
-       fd = open(SMACKFS_MNT "/load2", O_RDONLY);
+       snprintf(path, sizeof path, "%s/load2", smack_mnt);
+       fd = open(path, O_RDONLY);
        if (fd < 0)
                return -1;
 
index 5606e96..8446828 100644 (file)
@@ -26,7 +26,6 @@
 #define COMMON_H
 
 #define LABEL_LEN 255
-#define SMACKFS_MNT "/smack"
 #define ACCESSES_D_PATH "/etc/smack/accesses.d"
 #define CIPSO_D_PATH "/etc/smack/cipso.d"