diff options
Diffstat (limited to 'src/basic/selinux-util.c')
-rw-r--r-- | src/basic/selinux-util.c | 105 |
1 files changed, 60 insertions, 45 deletions
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c index a39a0f775a..a821a3d5bb 100644 --- a/src/basic/selinux-util.c +++ b/src/basic/selinux-util.c @@ -29,6 +29,7 @@ #include <selinux/context.h> #endif +#include "alloc-util.h" #include "strv.h" #include "path-util.h" #include "selinux-util.h" @@ -171,15 +172,15 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { int mac_selinux_apply(const char *path, const char *label) { #ifdef HAVE_SELINUX - assert(path); - assert(label); - if (!mac_selinux_use()) return 0; + assert(path); + assert(label); + 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) + if (security_getenforce() > 0) return -errno; } #endif @@ -295,21 +296,27 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char * return r; } -void mac_selinux_free(char *label) { +char* mac_selinux_free(char *label) { #ifdef HAVE_SELINUX + if (!label) + return NULL; + if (!mac_selinux_use()) - return; + return NULL; + freecon((security_context_t) label); #endif + + return NULL; } 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; + int r; assert(path); @@ -319,34 +326,33 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) { if (path_is_absolute(path)) r = selabel_lookup_raw(label_hnd, &filecon, path, mode); else { - _cleanup_free_ char *newpath; + _cleanup_free_ char *newpath = NULL; - newpath = path_make_absolute_cwd(path); - if (!newpath) - return -ENOMEM; + r = path_make_absolute_cwd(path, &newpath); + if (r < 0) + return r; r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode); } - /* No context specified by the policy? Proceed without setting it. */ - if (r < 0 && errno == ENOENT) - return 0; + if (r < 0) { + /* No context specified by the policy? Proceed without setting it. */ + if (errno == ENOENT) + return 0; - if (r < 0) - r = -errno; - else { - r = setfscreatecon(filecon); - if (r < 0) { - log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path); - r = -errno; - } + log_enforcing("Failed to determine SELinux security context for %s: %m", path); + } else { + if (setfscreatecon(filecon) >= 0) + return 0; /* Success! */ + + log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path); } - if (r < 0 && security_getenforce() == 0) - r = 0; -#endif + if (security_getenforce() > 0) + return -errno; - return r; +#endif + return 0; } void mac_selinux_create_file_clear(void) { @@ -399,6 +405,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { #ifdef HAVE_SELINUX _cleanup_security_context_free_ security_context_t fcon = NULL; const struct sockaddr_un *un; + bool context_changed = false; char *path; int r; @@ -414,7 +421,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { goto skipped; /* Filter out anonymous sockets */ - if (addrlen < sizeof(sa_family_t) + 1) + if (addrlen < offsetof(struct sockaddr_un, sun_path) + 1) goto skipped; /* Filter out abstract namespace sockets */ @@ -427,36 +434,44 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { if (path_is_absolute(path)) r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK); else { - _cleanup_free_ char *newpath; + _cleanup_free_ char *newpath = NULL; - newpath = path_make_absolute_cwd(path); - if (!newpath) - return -ENOMEM; + r = path_make_absolute_cwd(path, &newpath); + if (r < 0) + return r; r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK); } - if (r == 0) - r = setfscreatecon(fcon); + if (r < 0) { + /* No context specified by the policy? Proceed without setting it */ + if (errno == ENOENT) + goto skipped; - if (r < 0 && errno != ENOENT) { - log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path); + log_enforcing("Failed to determine SELinux security context for %s: %m", path); + if (security_getenforce() > 0) + return -errno; - if (security_getenforce() == 1) { - r = -errno; - goto finish; - } + } else { + if (setfscreatecon(fcon) < 0) { + log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path); + if (security_getenforce() > 0) + return -errno; + } else + context_changed = true; } - r = bind(fd, addr, addrlen); - if (r < 0) - r = -errno; + r = bind(fd, addr, addrlen) < 0 ? -errno : 0; + + if (context_changed) + setfscreatecon(NULL); -finish: - setfscreatecon(NULL); return r; skipped: #endif - return bind(fd, addr, addrlen) < 0 ? -errno : 0; + if (bind(fd, addr, addrlen) < 0) + return -errno; + + return 0; } |