diff options
Diffstat (limited to 'src/shared/label.c')
-rw-r--r-- | src/shared/label.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/shared/label.c b/src/shared/label.c index 25a8b361b7..dd89bec6e8 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -31,6 +31,7 @@ #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> +#include <selinux/context.h> #endif #include "label.h" @@ -243,6 +244,74 @@ fail: return r; } +int label_get_child_label(int socket_fd, const char *exe, char **label) { + int r = 0; + +#ifdef HAVE_SELINUX + + security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL; + security_class_t sclass; + context_t pcon = NULL, bcon = NULL; + const char *range = NULL; + + assert(socket_fd >= 0); + assert(exe); + assert(label); + + r = getcon(&mycon); + if (r < 0) + goto out; + + r = getpeercon(socket_fd, &peercon); + if (r < 0) + goto out; + + r = getfilecon(exe, &fcon); + if (r < 0) + goto out; + + bcon = context_new(mycon); + if (!bcon) + goto out; + + pcon = context_new(peercon); + if (!pcon) + goto out; + + range = context_range_get(pcon); + if (!range) + goto out; + + r = context_range_set(bcon, range); + if (r) + goto out; + + freecon(mycon); + mycon = context_str(bcon); + if (!mycon) + goto out; + + sclass = string_to_security_class("process"); + r = security_compute_create(mycon, fcon, sclass, &ret); + if (r < 0) + goto out; + + *label = ret; + +out: + if (r && security_getenforce() == 1) + r = -errno; + + freecon(mycon); + freecon(peercon); + freecon(fcon); + context_free(pcon); + context_free(bcon); + +#endif + return r; +} + int label_context_set(const char *path, mode_t mode) { int r = 0; |