summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
376a298)
APIs that query and return something cannot silently fail, they must
either return something useful, or an error. Fix that.
Also, properly rollback socket unit fd creation when something goes
wrong with the security framework.
continue;
if (p->type == SOCKET_SOCKET) {
continue;
if (p->type == SOCKET_SOCKET) {
- if (!know_label && s->selinux_context_from_net) {
- r = mac_selinux_get_our_label(&label);
- if (r < 0)
- return r;
- know_label = true;
- } else if (!know_label) {
- r = socket_instantiate_service(s);
- if (r < 0)
- return r;
+ if (!know_label) {
+ /* Figure out label, if we don't it know
+ * yet. We do it once, for the first
+ * socket where we need this and
+ * remember it for the rest. */
+
+ if (s->selinux_context_from_net) {
+ /* Get it from the network label */
+
+ r = mac_selinux_get_our_label(&label);
+ if (r < 0 && r != EOPNOTSUPP)
+ goto rollback;
- if (UNIT_ISSET(s->service) &&
- SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
- r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
- if (r < 0 && r != -EPERM)
- return r;
+ } else {
+ /* Get it from the executable we are about to start */
+
+ r = socket_instantiate_service(s);
+ if (r < 0)
+ goto rollback;
+
+ if (UNIT_ISSET(s->service) &&
+ SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
+ r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
+ if (r < 0 && r != -EPERM && r != EOPNOTSUPP)
+ goto rollback;
+ }
rollback:
socket_close_fds(s);
mac_selinux_free(label);
rollback:
socket_close_fds(s);
mac_selinux_free(label);
}
int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
}
int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
#ifdef HAVE_SELINUX
_cleanup_security_context_free_ security_context_t mycon = NULL, fcon = NULL;
security_class_t sclass;
#ifdef HAVE_SELINUX
_cleanup_security_context_free_ security_context_t mycon = NULL, fcon = NULL;
security_class_t sclass;
- if (!mac_selinux_use()) {
- *label = NULL;
- return 0;
- }
+ assert(exe);
+ assert(label);
+
+ if (!mac_selinux_use())
+ return -EOPNOTSUPP;
r = getcon(&mycon);
if (r < 0)
r = getcon(&mycon);
if (r < 0)
r = getfilecon(exe, &fcon);
if (r < 0)
r = getfilecon(exe, &fcon);
if (r < 0)
sclass = string_to_security_class("process");
r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
sclass = string_to_security_class("process");
r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
- if (r == 0)
- log_debug("SELinux Socket context for %s will be set to %s", exe, *label);
-
-fail:
- if (r < 0 && security_getenforce() == 1)
- r = -errno;
+ if (r < 0)
+ return -errno;
int mac_selinux_get_our_label(char **label) {
int r = -EOPNOTSUPP;
int mac_selinux_get_our_label(char **label) {
int r = -EOPNOTSUPP;
+ if (!mac_selinux_use())
+ return -EOPNOTSUPP;
- return r;
-
- *label = l;
int r = -EOPNOTSUPP;
#ifdef HAVE_SELINUX
int r = -EOPNOTSUPP;
#ifdef HAVE_SELINUX
-
- _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL;
+ _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL;
_cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
security_class_t sclass;
_cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
security_class_t sclass;
const char *range = NULL;
assert(socket_fd >= 0);
assert(exe);
assert(label);
const char *range = NULL;
assert(socket_fd >= 0);
assert(exe);
assert(label);
+ if (!mac_selinux_use())
+ return -EOPNOTSUPP;
+
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
+ if (r < 0)
+ return -errno;
r = getpeercon(socket_fd, &peercon);
r = getpeercon(socket_fd, &peercon);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
+ if (r < 0)
+ return -errno;
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
+ if (r < 0)
+ return -errno;
if (!fcon) {
/* If there is no context set for next exec let's use context
of target executable */
r = getfilecon(exe, &fcon);
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;
- }
+ if (r < 0)
+ return -errno;
}
bcon = context_new(mycon);
}
bcon = context_new(mycon);
- if (!bcon) {
- r = -ENOMEM;
- goto out;
- }
+ if (!bcon)
+ return -ENOMEM;
pcon = context_new(peercon);
pcon = context_new(peercon);
- if (!pcon) {
- r = -ENOMEM;
- goto out;
- }
+ if (!pcon)
+ return -ENOMEM;
range = context_range_get(pcon);
range = context_range_get(pcon);
- if (!range) {
- r = -errno;
- goto out;
- }
+ if (!range)
+ return -errno;
r = context_range_set(bcon, range);
r = context_range_set(bcon, range);
- if (r) {
- r = -errno;
- goto out;
- }
+ if (r)
+ return -errno;
freecon(mycon);
mycon = strdup(context_str(bcon));
freecon(mycon);
mycon = strdup(context_str(bcon));
- if (!mycon) {
- r = -errno;
- goto out;
- }
+ if (!mycon)
+ return -ENOMEM;
sclass = string_to_security_class("process");
sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, &ret);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
-
- *label = ret;
- ret = NULL;
- r = 0;
-
-out:
- if (r < 0 && security_getenforce() == 1)
- return r;
+ r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+ if (r < 0)
+ return -errno;