From 51f43b53293c4cc64c2a55598491c6cbf27b6bd5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 8 Apr 2011 01:03:49 +0200 Subject: [PATCH] selinux: do not label files in runtime dir Do not label any files in the udev runtime directory, but only nodes, links and directories below /dev. In case the runtime directory falls back to /dev/.udev, label this directory once at udevd startup, but never anything below it. --- libudev/libudev-private.h | 1 + libudev/libudev-queue-private.c | 2 -- libudev/libudev-util-private.c | 18 +++++++++++++++--- udev/udev-node.c | 6 +++--- udev/udevd.c | 18 ++++++++---------- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/libudev/libudev-private.h b/libudev/libudev-private.h index 7078b0ff3..8495f9aae 100644 --- a/libudev/libudev-private.h +++ b/libudev/libudev-private.h @@ -220,6 +220,7 @@ uint64_t util_string_bloom64(const char *str); /* libudev-util-private.c */ int util_create_path(struct udev *udev, const char *path); +int util_create_path_selinux(struct udev *udev, const char *path); int util_delete_path(struct udev *udev, const char *path); int util_unlink_secure(struct udev *udev, const char *filename); uid_t util_lookup_user(struct udev *udev, const char *user); diff --git a/libudev/libudev-queue-private.c b/libudev/libudev-queue-private.c index a71457236..2f1afecb2 100644 --- a/libudev/libudev-queue-private.c +++ b/libudev/libudev-queue-private.c @@ -409,9 +409,7 @@ static void update_failed(struct udev_queue_export *udev_queue_export, /* record event in the failed directory */ udev_queue_export->failed_count++; util_create_path(udev, filename); - udev_selinux_setfscreatecon(udev, filename, S_IFLNK); symlink(udev_device_get_devpath(udev_device), filename); - udev_selinux_resetfscreatecon(udev); break; case DEVICE_QUEUED: diff --git a/libudev/libudev-util-private.c b/libudev/libudev-util-private.c index 6b68b6a36..19f979eea 100644 --- a/libudev/libudev-util-private.c +++ b/libudev/libudev-util-private.c @@ -25,7 +25,7 @@ #include "libudev.h" #include "libudev-private.h" -int util_create_path(struct udev *udev, const char *path) +static int create_path(struct udev *udev, const char *path, bool selinux) { char p[UTIL_PATH_SIZE]; char *pos; @@ -55,7 +55,8 @@ int util_create_path(struct udev *udev, const char *path) return err; dbg(udev, "mkdir '%s'\n", p); - udev_selinux_setfscreatecon(udev, p, S_IFDIR|0755); + if (selinux) + udev_selinux_setfscreatecon(udev, p, S_IFDIR|0755); err = mkdir(p, 0755); if (err != 0) { err = -errno; @@ -66,10 +67,21 @@ int util_create_path(struct udev *udev, const char *path) err = -ENOTDIR; } } - udev_selinux_resetfscreatecon(udev); + if (selinux) + udev_selinux_resetfscreatecon(udev); return err; } +int util_create_path(struct udev *udev, const char *path) +{ + return create_path(udev, path, false); +} + +int util_create_path_selinux(struct udev *udev, const char *path) +{ + return create_path(udev, path, true); +} + int util_delete_path(struct udev *udev, const char *path) { char p[UTIL_PATH_SIZE]; diff --git a/udev/udev-node.c b/udev/udev-node.c index ab4e93228..5e791ffb6 100644 --- a/udev/udev-node.c +++ b/udev/udev-node.c @@ -96,7 +96,7 @@ int udev_node_mknod(struct udev_device *dev, const char *file, mode_t mode, uid_ } else { info(udev, "mknod '%s' %u:%u %#o\n", file, major(devnum), minor(devnum), mode); do { - err = util_create_path(udev, file); + err = util_create_path_selinux(udev, file); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, file, mode); @@ -184,7 +184,7 @@ static int node_symlink(struct udev *udev, const char *node, const char *slink) } else { info(udev, "creating symlink '%s' to '%s'\n", slink, target); do { - err = util_create_path(udev, slink); + err = util_create_path_selinux(udev, slink); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, slink, S_IFLNK); @@ -201,7 +201,7 @@ static int node_symlink(struct udev *udev, const char *node, const char *slink) util_strscpyl(slink_tmp, sizeof(slink_tmp), slink, TMP_FILE_EXT, NULL); unlink(slink_tmp); do { - err = util_create_path(udev, slink_tmp); + err = util_create_path_selinux(udev, slink_tmp); if (err != 0 && err != -ENOENT) break; udev_selinux_setfscreatecon(udev, slink_tmp, S_IFLNK); diff --git a/udev/udevd.c b/udev/udevd.c index a8b339fa1..df5c1995b 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -822,7 +822,7 @@ static void static_dev_create_from_modules(struct udev *udev) continue; util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/", devname, NULL); - util_create_path(udev, filename); + util_create_path_selinux(udev, filename); udev_selinux_setfscreatecon(udev, filename, mode); info(udev, "mknod '%s' %c%u:%u\n", filename, type, maj, min); if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST) @@ -833,7 +833,7 @@ static void static_dev_create_from_modules(struct udev *udev) fclose(f); } -static int copy_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth) +static int copy_dev_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth) { struct dirent *dent; @@ -886,7 +886,7 @@ static int copy_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth) continue; } - copy_dir(udev, dir2_from, dir2_to, maxdepth-1); + copy_dev_dir(udev, dir2_from, dir2_to, maxdepth-1); closedir(dir2_to); closedir(dir2_from); @@ -930,7 +930,7 @@ static void static_dev_create_from_devices(struct udev *udev, DIR *dir) dir_from = opendir(LIBEXECDIR "/devices"); if (dir_from == NULL) return; - copy_dir(udev, dir_from, dir, 8); + copy_dev_dir(udev, dir_from, dir, 8); closedir(dir_from); } @@ -985,9 +985,7 @@ static int convert_db(struct udev *udev) /* make sure we do not get here again */ util_create_path(udev, filename); - udev_selinux_setfscreatecon(udev, udev_get_run_path(udev), S_IFDIR|0755); mkdir(filename, 0755); - udev_selinux_resetfscreatecon(udev); /* old database */ util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/db", NULL); @@ -1097,9 +1095,7 @@ int main(int argc, char *argv[]) /* make sure, that our runtime dir exists and is writable */ if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) < 0) { /* try to create our own subdirectory, do not create parent directories */ - udev_selinux_setfscreatecon(udev, udev_get_run_config_path(udev), S_IFDIR|0755); mkdir(udev_get_run_config_path(udev), 0755); - udev_selinux_resetfscreatecon(udev); if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) >= 0) { /* directory seems writable now */ @@ -1111,8 +1107,12 @@ int main(int argc, char *argv[]) util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL); if (udev_set_run_path(udev, filename) == NULL) goto exit; + mkdir(udev_get_run_path(udev), 0755); } } + /* relabel runtime dir only if it resides below /dev */ + if (strncmp(udev_get_run_path(udev), udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) == 0) + udev_selinux_lsetfilecon(udev, udev_get_run_path(udev), 0755); info(udev, "runtime dir '%s'\n", udev_get_run_path(udev)); for (;;) { @@ -1281,9 +1281,7 @@ int main(int argc, char *argv[]) util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL); if (stat(filename, &statbuf) != 0) { util_create_path(udev, filename); - udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755); mkdir(filename, 0755); - udev_selinux_resetfscreatecon(udev); } inotify_add_watch(pfd[FD_INOTIFY].fd, filename, IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); -- 2.30.2