Smack - relabel directories and files created by systemd 80/13480/1 accepted/tizen/20131207.002722 accepted/tizen/20131209.172255 submit/tizen/20131206.214600
authorCasey Schaufler <casey@schaufler-ca.com>
Fri, 6 Dec 2013 19:40:22 +0000 (11:40 -0800)
committerCasey Schaufler <casey@schaufler-ca.com>
Fri, 6 Dec 2013 19:40:22 +0000 (11:40 -0800)
Systemd creates directories in /dev. These directories will
get the label of systemd, which is the label of the System
domain, which is not accessable to everyone. Relabel the
directories, files and symlinks created so that they can be
generally used.

Change-Id: I59f81c4be116647748a4ca3a94f9061c1b64fb85
Signed-off-by: Casey Schaufler <casey.schaufler@intel.com.com>
src/shared/label.c

index fde39f2..ad73981 100644 (file)
 static struct selabel_handle *label_hnd = NULL;
 
 #endif
+#ifdef HAVE_SMACK
+#include <sys/xattr.h>
+#include <string.h>
+#define DEV_DIR                "/dev"
+#define DEV_PATH       "/dev/"
+#define DEV_PATH_LEN   5
+#define FLOOR_LABEL    "_"
+#define STAR_LABEL     "*"
+
+static void smack_relabel_in_dev(const char *path) {
+       struct stat sb;
+       const char *label;
+       int r;
+
+       /*
+        * Path must be in /dev and must exist
+        */
+       if (strcmp(path, DEV_DIR) &&
+           strncmp(path, DEV_PATH, DEV_PATH_LEN))
+               return;
+
+       r = lstat(path, &sb);
+       if (r < 0)
+               return;
+
+       /*
+        * Label directories and character devices "*".
+        * Label symlinks "_".
+        * Don't change anything else.
+        */
+       if (S_ISDIR(sb.st_mode))
+               label = STAR_LABEL;
+       else if (S_ISLNK(sb.st_mode))
+               label = FLOOR_LABEL;
+       else if (S_ISCHR(sb.st_mode))
+               label = STAR_LABEL;
+       else
+               return;
+
+       r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
+       if (r < 0)
+               log_error("Smack relabeling \"%s\" %s", path, strerror(errno));
+       return;
+}
+#endif
 
 int label_init(const char *prefix) {
         int r = 0;
@@ -131,6 +176,9 @@ int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
                 r = security_getenforce() == 1 ? -errno : 0;
         }
 #endif
+#ifdef HAVE_SMACK
+       smack_relabel_in_dev(path);
+#endif
 
         return r;
 }
@@ -205,6 +253,9 @@ int label_context_set(const char *path, mode_t mode) {
         if (r < 0 && security_getenforce() == 0)
                 r = 0;
 #endif
+#ifdef HAVE_SMACK
+       smack_relabel_in_dev(path);
+#endif
 
         return r;
 }
@@ -258,10 +309,10 @@ void label_free(const char *label) {
 }
 
 int label_mkdir(const char *path, mode_t mode) {
+        int r;
 
-        /* Creates a directory and labels it according to the SELinux policy */
 #ifdef HAVE_SELINUX
-        int r;
+        /* Creates a directory and labels it according to the SELinux policy */
         security_context_t fcon = NULL;
 
         if (!use_selinux() || !label_hnd)
@@ -304,7 +355,13 @@ finish:
 
 skipped:
 #endif
-        return mkdir(path, mode) < 0 ? -errno : 0;
+        r = mkdir(path, mode);
+       if (r)
+               return -errno;
+#ifdef HAVE_SMACK
+       smack_relabel_in_dev(path);
+#endif
+       return 0;
 }
 
 int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {