From 82b9638be653c3f0a3710e67436a0c167469e0c7 Mon Sep 17 00:00:00 2001 From: Kay Sievers <kay@vrfy.org> Date: Tue, 17 Apr 2012 16:05:03 +0200 Subject: [PATCH] selinux: unify systemd and udev code (cherry picked from commit e9a5ef7cddcfcdb29b5aef3896931132b6fd5165) Conflicts: Makefile.am src/libudev/libudev-private.h src/test/test-udev.c src/udev/udev-node.c src/udev/udev.h src/udev/udevadm.c src/udev/udevd.c --- src/core/main.c | 2 +- src/core/mount-setup.c | 5 +++-- src/core/socket.c | 7 ++++--- src/shared/label.c | 47 +++++++++++++---------------------------------- src/shared/label.h | 7 +++---- src/tmpfiles/tmpfiles.c | 17 +++++++++++++++-- 6 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 80ef8b1..e6b3353 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1222,7 +1222,7 @@ int main(int argc, char *argv[]) { log_open(); - if (label_init() < 0) + if (label_init(NULL) < 0) goto finish; if (!is_reexec) diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index dd7938e..eeec251 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -329,13 +329,14 @@ static int symlink_and_label(const char *old_path, const char *new_path) { assert(old_path); assert(new_path); - if ((r = label_symlinkfile_set(new_path)) < 0) + r = label_context_set(new_path, S_IFLNK); + if (r < 0) return r; if (symlink(old_path, new_path) < 0) r = -errno; - label_file_clear(); + label_context_clear(); return r; } diff --git a/src/core/socket.c b/src/core/socket.c index 87d6d86..d03b35c 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -762,7 +762,8 @@ static int fifo_address_create( mkdir_parents(path, directory_mode); - if ((r = label_fifofile_set(path)) < 0) + r = label_context_set(path, S_IFIFO); + if (r < 0) goto fail; /* Enforce the right access mode for the fifo */ @@ -784,7 +785,7 @@ static int fifo_address_create( goto fail; } - label_file_clear(); + label_context_clear(); if (fstat(fd, &st) < 0) { r = -errno; @@ -804,7 +805,7 @@ static int fifo_address_create( return 0; fail: - label_file_clear(); + label_context_clear(); if (fd >= 0) close_nointr_nofail(fd); diff --git a/src/shared/label.c b/src/shared/label.c index 2c887a0..433b768 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -51,7 +51,7 @@ void label_retest_selinux(void) { #endif -int label_init(void) { +int label_init(const char *prefix) { int r = 0; #ifdef HAVE_SELINUX @@ -67,7 +67,15 @@ int label_init(void) { before_mallinfo = mallinfo(); before_timestamp = now(CLOCK_MONOTONIC); - label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (prefix) { + struct selinux_opt options[] = { + { .type = SELABEL_OPT_SUBSET, .value = prefix }, + }; + + label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options)); + } else + label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (!label_hnd) { log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, "Failed to initialize SELinux context: %m"); @@ -177,36 +185,7 @@ fail: return r; } -int label_fifofile_set(const char *path) { - int r = 0; - -#ifdef HAVE_SELINUX - security_context_t filecon = NULL; - - if (!use_selinux() || !label_hnd) - return 0; - - r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFIFO); - if (r < 0) - r = -errno; - else if (r == 0) { - r = setfscreatecon(filecon); - if (r < 0) { - log_error("Failed to set SELinux file context on %s: %m", path); - r = -errno; - } - - freecon(filecon); - } - - if (r < 0 && security_getenforce() == 0) - r = 0; -#endif - - return r; -} - -int label_symlinkfile_set(const char *path) { +int label_context_set(const char *path, mode_t mode) { int r = 0; #ifdef HAVE_SELINUX @@ -215,7 +194,7 @@ int label_symlinkfile_set(const char *path) { if (!use_selinux() || !label_hnd) return 0; - r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFLNK); + r = selabel_lookup_raw(label_hnd, &filecon, path, mode); if (r < 0) r = -errno; else if (r == 0) { @@ -253,7 +232,7 @@ int label_socket_set(const char *label) { return 0; } -void label_file_clear(void) { +void label_context_clear(void) { #ifdef HAVE_SELINUX if (!use_selinux()) diff --git a/src/shared/label.h b/src/shared/label.h index ead4483..6166bc3 100644 --- a/src/shared/label.h +++ b/src/shared/label.h @@ -26,7 +26,7 @@ #include <stdbool.h> #include <sys/socket.h> -int label_init(void); +int label_init(const char *prefix); void label_finish(void); int label_fix(const char *path, bool ignore_enoent); @@ -34,9 +34,8 @@ int label_fix(const char *path, bool ignore_enoent); int label_socket_set(const char *label); void label_socket_clear(void); -int label_fifofile_set(const char *path); -int label_symlinkfile_set(const char *path); -void label_file_clear(void); +int label_context_set(const char *path, mode_t mode); +void label_context_clear(void); void label_free(const char *label); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index c5f6fc0..d3ea592 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -562,7 +562,7 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) { } static int create_item(Item *i) { - int r; + int r, e; mode_t u; struct stat st; @@ -584,8 +584,12 @@ static int create_item(Item *i) { i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0; u = umask(0); + label_context_set(i->path, S_IFREG); fd = open(i->path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode); + e = errno; + label_context_clear(); umask(u); + errno = e; if (fd < 0) { if (i->type == WRITE_FILE && errno == ENOENT) @@ -696,7 +700,12 @@ static int create_item(Item *i) { case CREATE_SYMLINK: { char *x; + label_context_set(i->path, S_IFLNK); r = symlink(i->argument, i->path); + e = errno; + label_context_clear(); + errno = e; + if (r < 0 && errno != EEXIST) { log_error("symlink(%s, %s) failed: %m", i->argument, i->path); return -errno; @@ -722,8 +731,12 @@ static int create_item(Item *i) { case CREATE_CHAR_DEVICE: { u = umask(0); + label_context_set(i->path, CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); r = mknod(i->path, i->mode | (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR), i->major_minor); + e = errno; + label_context_clear(); umask(u); + errno = e; if (r < 0 && errno != EEXIST) { log_error("Failed to create device node %s: %m", i->path); @@ -1248,7 +1261,7 @@ int main(int argc, char *argv[]) { umask(0022); - label_init(); + label_init(NULL); items = hashmap_new(string_hash_func, string_compare_func); globs = hashmap_new(string_hash_func, string_compare_func);