X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Flabel.c;h=b6af38d82d39a0940c6133c4ca886d7384c59cdb;hp=dd89bec6e89a5aa7738d9f7cc76550df35030e5c;hb=493d521d9ffe706741665a88ea14929913ea2eaf;hpb=cf8bd44339b00330fdbc91041d6731ba8aba9fec diff --git a/src/shared/label.c b/src/shared/label.c index dd89bec6e..b6af38d82 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -42,6 +42,12 @@ #include "smack-util.h" #ifdef HAVE_SELINUX +DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon); +DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free); + +#define _cleanup_security_context_free_ _cleanup_(freeconp) +#define _cleanup_context_free_ _cleanup_(context_freep) + static struct selabel_handle *label_hnd = NULL; #endif @@ -244,14 +250,31 @@ fail: return r; } -int label_get_child_label(int socket_fd, const char *exe, char **label) { - int r = 0; +int label_get_our_label(char **label) { + int r = -EOPNOTSUPP; #ifdef HAVE_SELINUX + char *l = NULL; + + r = getcon(&l); + if (r < 0) + return r; + + *label = l; +#endif + + return r; +} + +int label_get_child_mls_label(int socket_fd, const char *exe, char **label) { + int r = -EOPNOTSUPP; - security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL; +#ifdef HAVE_SELINUX + + _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL; + _cleanup_context_free_ context_t pcon = NULL, bcon = NULL; security_class_t sclass; - context_t pcon = NULL, bcon = NULL; + const char *range = NULL; assert(socket_fd >= 0); @@ -259,55 +282,77 @@ int label_get_child_label(int socket_fd, const char *exe, char **label) { assert(label); r = getcon(&mycon); - if (r < 0) + if (r < 0) { + r = -EINVAL; goto out; + } r = getpeercon(socket_fd, &peercon); - if (r < 0) + if (r < 0) { + r = -EINVAL; goto out; + } - r = getfilecon(exe, &fcon); - if (r < 0) + r = getexeccon(&fcon); + if (r < 0) { + r = -EINVAL; goto out; + } + + if (!fcon) { + /* If there is no context set for next exec let's use context + of target executable */ + r = getfilecon(exe, &fcon); + if (r < 0) { + r = -errno; + goto out; + } + } bcon = context_new(mycon); - if (!bcon) + if (!bcon) { + r = -ENOMEM; goto out; + } pcon = context_new(peercon); - if (!pcon) + if (!pcon) { + r = -ENOMEM; goto out; + } range = context_range_get(pcon); - if (!range) + if (!range) { + r = -errno; goto out; + } r = context_range_set(bcon, range); - if (r) + if (r) { + r = -errno; goto out; + } freecon(mycon); mycon = context_str(bcon); - if (!mycon) + if (!mycon) { + r = -errno; goto out; + } sclass = string_to_security_class("process"); r = security_compute_create(mycon, fcon, sclass, &ret); - if (r < 0) + if (r < 0) { + r = -EINVAL; goto out; + } *label = ret; + r = 0; out: - if (r && security_getenforce() == 1) - r = -errno; - - freecon(mycon); - freecon(peercon); - freecon(fcon); - context_free(pcon); - context_free(bcon); - + if (r < 0 && security_getenforce() == 1) + return r; #endif return r; }