X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fselinux-util.c;h=6bd3bf1c8027c651a928692b2773e21a32c7b63e;hp=c59ad31edaef623caa59e19d0db6cdaf822fe530;hb=79008bddf679a5e0900369950eb346c9fa687107;hpb=7f416dae9bcf1cfb63689ee9ac851adf738f072b diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c index c59ad31ed..6bd3bf1c8 100644 --- a/src/shared/selinux-util.c +++ b/src/shared/selinux-util.c @@ -23,6 +23,7 @@ #include #include #include + #ifdef HAVE_SELINUX #include #include @@ -42,6 +43,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); static int cached_use = -1; static struct selabel_handle *label_hnd = NULL; + +#define log_enforcing(...) log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, __VA_ARGS__) #endif bool mac_selinux_use(void) { @@ -87,8 +90,7 @@ int mac_selinux_init(const char *prefix) { 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"); + log_enforcing("Failed to initialize SELinux context: %m"); r = security_getenforce() == 1 ? -errno : 0; } else { char timespan[FORMAT_TIMESPAN_MAX]; @@ -108,11 +110,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); @@ -147,22 +159,31 @@ int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { if (ignore_erofs && errno == EROFS) return 0; - log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, "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) { @@ -278,22 +299,49 @@ 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; - if (!mac_selinux_use() || !label_hnd) + assert(path); + + if (!label_hnd) return 0; - r = selabel_lookup_raw(label_hnd, &filecon, path, mode); - if (r < 0 && errno != ENOENT) + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &filecon, path, mode); + else { + _cleanup_free_ char *newpath; + + newpath = path_make_absolute_cwd(path); + if (!newpath) + return -ENOMEM; + + 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) r = -errno; - else if (r == 0) { + else { r = setfscreatecon(filecon); if (r < 0) { - log_error("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; } } @@ -305,25 +353,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_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, - "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,71 +365,35 @@ void mac_selinux_context_clear(void) { #endif } -void mac_selinux_socket_clear(void) { - -#ifdef HAVE_SELINUX - PROTECT_ERRNO; - - if (!mac_selinux_use()) - return; - - setsockcreatecon(NULL); -#endif -} - -void mac_selinux_free(const char *label) { +int mac_selinux_create_socket_prepare(const char *label) { #ifdef HAVE_SELINUX if (!mac_selinux_use()) - return; - - freecon((security_context_t) label); -#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 */ - _cleanup_security_context_free_ security_context_t fcon = NULL; - - if (!label_hnd) return 0; - if (path_is_absolute(path)) - r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR); - else { - _cleanup_free_ char *newpath; + assert(label); - newpath = path_make_absolute_cwd(path); - if (!newpath) - return -ENOMEM; + if (setsockcreatecon((security_context_t) label) < 0) { + log_enforcing("Failed to set SELinux security context %s for sockets: %m", label); - r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR); + if (security_getenforce() == 1) + return -errno; } +#endif - if (r == 0) - r = setfscreatecon(fcon); + return 0; +} - if (r < 0 && errno != ENOENT) { - log_error("Failed to set security context %s for %s: %m", fcon, path); +void mac_selinux_create_socket_clear(void) { - if (security_getenforce() == 1) { - r = -errno; - goto finish; - } - } +#ifdef HAVE_SELINUX + PROTECT_ERRNO; - r = mkdir(path, mode); - if (r < 0) - r = -errno; + if (!mac_selinux_use()) + return; -finish: - setfscreatecon(NULL); + setsockcreatecon(NULL); #endif - - return r; } int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { @@ -416,7 +410,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 +444,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { r = setfscreatecon(fcon); if (r < 0 && errno != ENOENT) { - log_error("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 +464,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; -}