summaryrefslogtreecommitdiff
path: root/src/basic/selinux-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/selinux-util.c')
-rw-r--r--src/basic/selinux-util.c105
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;
}