diff options
-rw-r--r-- | src/core/namespace.c | 4 | ||||
-rw-r--r-- | src/core/socket.c | 6 | ||||
-rw-r--r-- | src/shared/dev-setup.c | 4 | ||||
-rw-r--r-- | src/shared/fileio-label.c | 12 | ||||
-rw-r--r-- | src/shared/selinux-util.c | 126 | ||||
-rw-r--r-- | src/shared/selinux-util.h | 20 | ||||
-rw-r--r-- | src/shared/socket-label.c | 4 | ||||
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 28 | ||||
-rw-r--r-- | src/udev/udev-node.c | 11 | ||||
-rw-r--r-- | src/update-done/update-done.c | 4 |
10 files changed, 117 insertions, 102 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c index 6dd7a4f25e..4bc288de1d 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -225,9 +225,9 @@ static int mount_dev(BindMount *m) { goto fail; } - mac_selinux_context_set(d, st.st_mode); + mac_selinux_create_file_prepare(d, st.st_mode); r = mknod(dn, st.st_mode, st.st_rdev); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); if (r < 0) { r = -errno; diff --git a/src/core/socket.c b/src/core/socket.c index e9cf7b3e93..dc16af5e39 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -967,7 +967,7 @@ static int fifo_address_create( mkdir_parents_label(path, directory_mode); - r = mac_selinux_context_set(path, S_IFIFO); + r = mac_selinux_create_file_prepare(path, S_IFIFO); if (r < 0) goto fail; @@ -990,7 +990,7 @@ static int fifo_address_create( goto fail; } - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); if (fstat(fd, &st) < 0) { r = -errno; @@ -1010,7 +1010,7 @@ static int fifo_address_create( return 0; fail: - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); safe_close(fd); return r; diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index 96934a9fad..ae1c3d9d4e 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -38,14 +38,14 @@ static int symlink_and_label(const char *old_path, const char *new_path) { assert(old_path); assert(new_path); - r = mac_selinux_context_set(new_path, S_IFLNK); + r = mac_selinux_create_file_prepare(new_path, S_IFLNK); if (r < 0) return r; if (symlink(old_path, new_path) < 0) r = -errno; - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); return r; } diff --git a/src/shared/fileio-label.c b/src/shared/fileio-label.c index b117c32cf2..294c9e6bad 100644 --- a/src/shared/fileio-label.c +++ b/src/shared/fileio-label.c @@ -30,13 +30,13 @@ int write_string_file_atomic_label(const char *fn, const char *line) { int r; - r = mac_selinux_context_set(fn, S_IFREG); + r = mac_selinux_create_file_prepare(fn, S_IFREG); if (r < 0) return r; r = write_string_file_atomic(fn, line); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); return r; } @@ -44,13 +44,13 @@ int write_string_file_atomic_label(const char *fn, const char *line) { int write_env_file_label(const char *fname, char **l) { int r; - r = mac_selinux_context_set(fname, S_IFREG); + r = mac_selinux_create_file_prepare(fname, S_IFREG); if (r < 0) return r; r = write_env_file(fname, l); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); return r; } @@ -59,13 +59,13 @@ int fopen_temporary_label(const char *target, const char *path, FILE **f, char **temp_path) { int r; - r = mac_selinux_context_set(target, S_IFREG); + r = mac_selinux_create_file_prepare(target, S_IFREG); if (r < 0) return r; r = fopen_temporary(path, f, temp_path); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); return r; } diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index 76d3916ea7..0d8c6c2f1c 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -109,11 +109,21 @@ int mac_selinux_init(const char *prefix) { return r; } +void mac_selinux_finish(void) { + +#ifdef HAVE_SELINUX + if (!label_hnd) + return; + + selabel_close(label_hnd); +#endif +} + int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { - int r = 0; #ifdef HAVE_SELINUX struct stat st; + int r; assert(path); @@ -148,22 +158,31 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { if (ignore_erofs && errno == EROFS) return 0; - log_enforcing("Unable to fix SELinux label of %s: %m", path); - r = security_getenforce() == 1 ? -errno : 0; + log_enforcing("Unable to fix SELinux security context of %s: %m", path); + if (security_getenforce() == 1) + return -errno; } #endif - return r; + return 0; } -void mac_selinux_finish(void) { +int mac_selinux_apply(const char *path, const char *label) { #ifdef HAVE_SELINUX - if (!label_hnd) - return; + assert(path); + assert(label); - selabel_close(label_hnd); + if (!mac_selinux_use()) + return 0; + + if (setfilecon(path, (security_context_t) label) < 0) { + log_enforcing("Failed to set SELinux security context %s on path %s: %m", label, path); + if (security_getenforce() == 1) + return -errno; + } #endif + return 0; } int mac_selinux_get_create_label_from_exe(const char *exe, char **label) { @@ -279,12 +298,24 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, char **label return r; } -int mac_selinux_context_set(const char *path, mode_t mode) { +void mac_selinux_free(char *label) { + +#ifdef HAVE_SELINUX + if (!mac_selinux_use()) + return; + + freecon((security_context_t) label); +#endif +} + +int mac_selinux_create_file_prepare(const char *path, mode_t mode) { int r = 0; #ifdef HAVE_SELINUX _cleanup_security_context_free_ security_context_t filecon = NULL; + assert(path); + if (!label_hnd) return 0; @@ -294,7 +325,7 @@ int mac_selinux_context_set(const char *path, mode_t mode) { else if (r == 0) { r = setfscreatecon(filecon); if (r < 0) { - log_enforcing("Failed to set SELinux file context on %s: %m", path); + log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path); r = -errno; } } @@ -306,24 +337,7 @@ int mac_selinux_context_set(const char *path, mode_t mode) { return r; } -int mac_selinux_socket_set(const char *label) { - -#ifdef HAVE_SELINUX - if (!mac_selinux_use()) - return 0; - - if (setsockcreatecon((security_context_t) label) < 0) { - log_enforcing("Failed to set SELinux context (%s) on socket: %m", label); - - if (security_getenforce() == 1) - return -errno; - } -#endif - - return 0; -} - -void mac_selinux_context_clear(void) { +void mac_selinux_create_file_clear(void) { #ifdef HAVE_SELINUX PROTECT_ERRNO; @@ -335,37 +349,49 @@ void mac_selinux_context_clear(void) { #endif } -void mac_selinux_socket_clear(void) { +int mac_selinux_create_socket_prepare(const char *label) { #ifdef HAVE_SELINUX - PROTECT_ERRNO; - if (!mac_selinux_use()) - return; + return 0; - setsockcreatecon(NULL); + assert(label); + + if (setsockcreatecon((security_context_t) label) < 0) { + log_enforcing("Failed to set SELinux security context %s for sockets: %m", label); + + if (security_getenforce() == 1) + return -errno; + } #endif + + return 0; } -void mac_selinux_free(const char *label) { +void mac_selinux_create_socket_clear(void) { #ifdef HAVE_SELINUX + PROTECT_ERRNO; + if (!mac_selinux_use()) return; - freecon((security_context_t) label); + setsockcreatecon(NULL); #endif } int mac_selinux_mkdir(const char *path, mode_t mode) { - int r = 0; -#ifdef HAVE_SELINUX /* Creates a directory and labels it according to the SELinux policy */ + +#ifdef HAVE_SELINUX _cleanup_security_context_free_ security_context_t fcon = NULL; + int r; + + assert(path); if (!label_hnd) - return 0; + goto skipped; if (path_is_absolute(path)) r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR); @@ -383,7 +409,7 @@ int mac_selinux_mkdir(const char *path, mode_t mode) { r = setfscreatecon(fcon); if (r < 0 && errno != ENOENT) { - log_enforcing("Failed to set security context %s for %s: %m", fcon, path); + log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path); if (security_getenforce() == 1) { r = -errno; @@ -397,9 +423,11 @@ int mac_selinux_mkdir(const char *path, mode_t mode) { finish: setfscreatecon(NULL); -#endif - return r; + +skipped: +#endif + return mkdir(path, mode) < 0 ? -errno : 0; } int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { @@ -416,7 +444,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { assert(addr); assert(addrlen >= sizeof(sa_family_t)); - if (!mac_selinux_use() || !label_hnd) + if (!label_hnd) goto skipped; /* Filter out non-local sockets */ @@ -450,7 +478,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { r = setfscreatecon(fcon); if (r < 0 && errno != ENOENT) { - log_enforcing("Failed to set security context %s for %s: %m", fcon, path); + log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path); if (security_getenforce() == 1) { r = -errno; @@ -470,15 +498,3 @@ skipped: #endif return bind(fd, addr, addrlen) < 0 ? -errno : 0; } - -int mac_selinux_apply(const char *path, const char *label) { - int r = 0; - -#ifdef HAVE_SELINUX - if (!mac_selinux_use()) - return 0; - - r = setfilecon(path, (char *)label); -#endif - return r; -} diff --git a/src/shared/selinux-util.h b/src/shared/selinux-util.h index 80546986d2..bce9fd5d46 100644 --- a/src/shared/selinux-util.h +++ b/src/shared/selinux-util.h @@ -32,20 +32,18 @@ int mac_selinux_init(const char *prefix); void mac_selinux_finish(void); int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs); - -int mac_selinux_socket_set(const char *label); -void mac_selinux_socket_clear(void); - -int mac_selinux_context_set(const char *path, mode_t mode); -void mac_selinux_context_clear(void); - -int mac_selinux_mkdir(const char *path, mode_t mode); +int mac_selinux_apply(const char *path, const char *label); int mac_selinux_get_create_label_from_exe(const char *exe, char **label); int mac_selinux_get_our_label(char **label); int mac_selinux_get_child_mls_label(int socket_fd, const char *exec, char **label); -void mac_selinux_free(const char *label); +void mac_selinux_free(char *label); -int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); +int mac_selinux_create_file_prepare(const char *path, mode_t mode); +void mac_selinux_create_file_clear(void); -int mac_selinux_apply(const char *path, const char *label); +int mac_selinux_create_socket_prepare(const char *label); +void mac_selinux_create_socket_clear(void); + +int mac_selinux_mkdir(const char *path, mode_t mode); +int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/src/shared/socket-label.c b/src/shared/socket-label.c index 6f9aeeea5d..47d9488d56 100644 --- a/src/shared/socket-label.c +++ b/src/shared/socket-label.c @@ -64,7 +64,7 @@ int socket_address_listen( return -EAFNOSUPPORT; if (label) { - r = mac_selinux_socket_set(label); + r = mac_selinux_create_socket_prepare(label); if (r < 0) return r; } @@ -73,7 +73,7 @@ int socket_address_listen( r = fd < 0 ? -errno : 0; if (label) - mac_selinux_socket_clear(); + mac_selinux_create_socket_clear(); if (r < 0) return r; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 28c395bb00..1e4675f87e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -509,9 +509,9 @@ static int write_one_file(Item *i, const char *path) { i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0; RUN_WITH_UMASK(0000) { - mac_selinux_context_set(path, S_IFREG); + mac_selinux_create_file_prepare(path, S_IFREG); fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } if (fd < 0) { @@ -743,9 +743,9 @@ static int create_item(Item *i) { case CREATE_FIFO: RUN_WITH_UMASK(0000) { - mac_selinux_context_set(i->path, S_IFIFO); + mac_selinux_create_file_prepare(i->path, S_IFIFO); r = mkfifo(i->path, i->mode); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } if (r < 0) { @@ -764,9 +764,9 @@ static int create_item(Item *i) { if (i->force) { RUN_WITH_UMASK(0000) { - mac_selinux_context_set(i->path, S_IFIFO); + mac_selinux_create_file_prepare(i->path, S_IFIFO); r = mkfifo_atomic(i->path, i->mode); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } if (r < 0) { @@ -788,9 +788,9 @@ static int create_item(Item *i) { case CREATE_SYMLINK: - mac_selinux_context_set(i->path, S_IFLNK); + mac_selinux_create_file_prepare(i->path, S_IFLNK); r = symlink(i->argument, i->path); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); if (r < 0) { _cleanup_free_ char *x = NULL; @@ -804,9 +804,9 @@ static int create_item(Item *i) { if (r < 0 || !streq(i->argument, x)) { if (i->force) { - mac_selinux_context_set(i->path, S_IFLNK); + mac_selinux_create_file_prepare(i->path, S_IFLNK); r = symlink_atomic(i->argument, i->path); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); if (r < 0) { log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r)); @@ -838,9 +838,9 @@ static int create_item(Item *i) { file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR; RUN_WITH_UMASK(0000) { - mac_selinux_context_set(i->path, file_type); + mac_selinux_create_file_prepare(i->path, file_type); r = mknod(i->path, i->mode | file_type, i->major_minor); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } if (r < 0) { @@ -865,9 +865,9 @@ static int create_item(Item *i) { if (i->force) { RUN_WITH_UMASK(0000) { - mac_selinux_context_set(i->path, file_type); + mac_selinux_create_file_prepare(i->path, file_type); r = mknod_atomic(i->path, i->mode | file_type, i->major_minor); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } if (r < 0) { diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 8d5bada5a4..4ac6f71490 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -88,11 +88,11 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s err = mkdir_parents_label(slink, 0755); if (err != 0 && err != -ENOENT) break; - mac_selinux_context_set(slink, S_IFLNK); + mac_selinux_create_file_prepare(slink, S_IFLNK); err = symlink(target, slink); if (err != 0) err = -errno; - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } while (err == -ENOENT); if (err == 0) goto exit; @@ -105,11 +105,11 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s err = mkdir_parents_label(slink_tmp, 0755); if (err != 0 && err != -ENOENT) break; - mac_selinux_context_set(slink_tmp, S_IFLNK); + mac_selinux_create_file_prepare(slink_tmp, S_IFLNK); err = symlink(target, slink_tmp); if (err != 0) err = -errno; - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); } while (err == -ENOENT); if (err != 0) { log_error("symlink '%s' '%s' failed: %m", target, slink_tmp); @@ -302,7 +302,8 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, if (streq(name, "selinux")) { selinux = true; - if (mac_selinux_apply(devnode, label) < 0) + r = mac_selinux_apply(devnode, label); + if (r < 0) log_error("SECLABEL: failed to set SELinux label '%s': %s", label, strerror(-r)); else log_debug("SECLABEL: set SELinux label '%s'", label); diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c index d48e4f76d5..1437c30d14 100644 --- a/src/update-done/update-done.c +++ b/src/update-done/update-done.c @@ -61,7 +61,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) { /* The timestamp file doesn't exist yet? Then let's create it. */ - r = mac_selinux_context_set(path, S_IFREG); + r = mac_selinux_create_file_prepare(path, S_IFREG); if (r < 0) { log_error("Failed to set SELinux context for %s: %s", path, strerror(-r)); @@ -69,7 +69,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) { } fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); - mac_selinux_context_clear(); + mac_selinux_create_file_clear(); if (fd < 0) { |