diff options
-rw-r--r-- | src/shared/dev-setup.c | 4 | ||||
-rw-r--r-- | src/shared/selinux-util.c | 126 | ||||
-rw-r--r-- | src/shared/selinux-util.h | 20 | ||||
-rw-r--r-- | src/udev/udev-node.c | 11 |
4 files changed, 88 insertions, 73 deletions
diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index 10f74f0ccb..fb16a8a8cc 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -36,14 +36,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/selinux-util.c b/src/shared/selinux-util.c index b4ac441c21..c4223240f9 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -107,11 +107,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); @@ -146,22 +156,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) { @@ -277,12 +296,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; @@ -292,7 +323,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; } } @@ -304,24 +335,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; @@ -333,37 +347,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); @@ -381,7 +407,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; @@ -395,9 +421,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) { @@ -414,7 +442,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 */ @@ -448,7 +476,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; @@ -468,15 +496,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 22f529a41c..cc1986d780 100644 --- a/src/shared/selinux-util.h +++ b/src/shared/selinux-util.h @@ -30,20 +30,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/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); |