mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-06 13:17:44 +03:00
tree-wide: have_effective_cap() may return negative errno
This commit is contained in:
parent
d7301331e8
commit
26c45a6c1d
@ -79,6 +79,7 @@ bool argv_looks_like_help(int argc, char **argv) {
|
||||
|
||||
static int update_argv(const char name[], size_t l) {
|
||||
static int can_do = -1;
|
||||
int r;
|
||||
|
||||
if (can_do == 0)
|
||||
return 0;
|
||||
@ -86,13 +87,15 @@ static int update_argv(const char name[], size_t l) {
|
||||
|
||||
/* Calling prctl() with PR_SET_MM_ARG_{START,END} requires CAP_SYS_RESOURCE so let's use this as quick bypass
|
||||
* check, to avoid calling mmap() should PR_SET_MM_ARG_{START,END} fail with EPERM later on anyway. */
|
||||
if (!have_effective_cap(CAP_SYS_RESOURCE))
|
||||
r = have_effective_cap(CAP_SYS_RESOURCE);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to check if we have enough privileges: %m");
|
||||
if (r == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
|
||||
"Skipping PR_SET_MM, as we don't have privileges.");
|
||||
|
||||
static size_t mm_size = 0;
|
||||
static char *mm = NULL;
|
||||
int r;
|
||||
|
||||
if (mm_size < l+1) {
|
||||
size_t nn_size;
|
||||
|
@ -19,7 +19,7 @@ static int audit_fd;
|
||||
int get_audit_fd(void) {
|
||||
|
||||
if (!initialized) {
|
||||
if (have_effective_cap(CAP_AUDIT_WRITE) == 0) {
|
||||
if (have_effective_cap(CAP_AUDIT_WRITE) <= 0) {
|
||||
audit_fd = -EPERM;
|
||||
initialized = true;
|
||||
|
||||
|
@ -1433,7 +1433,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) {
|
||||
if (c->no_new_privileges)
|
||||
return true;
|
||||
|
||||
if (have_effective_cap(CAP_SYS_ADMIN)) /* if we are privileged, we don't need NNP */
|
||||
if (have_effective_cap(CAP_SYS_ADMIN) > 0) /* if we are privileged, we don't need NNP */
|
||||
return false;
|
||||
|
||||
/* We need NNP if we have any form of seccomp and are unprivileged */
|
||||
@ -2117,7 +2117,7 @@ static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) {
|
||||
* does not need CAP_SETUID to write the single line mapping to itself. */
|
||||
|
||||
/* Can only set up multiple mappings with CAP_SETUID. */
|
||||
if (have_effective_cap(CAP_SETUID) && uid != ouid && uid_is_valid(uid))
|
||||
if (have_effective_cap(CAP_SETUID) > 0 && uid != ouid && uid_is_valid(uid))
|
||||
r = asprintf(&uid_map,
|
||||
UID_FMT " " UID_FMT " 1\n" /* Map $OUID → $OUID */
|
||||
UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */
|
||||
@ -2131,7 +2131,7 @@ static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) {
|
||||
return -ENOMEM;
|
||||
|
||||
/* Can only set up multiple mappings with CAP_SETGID. */
|
||||
if (have_effective_cap(CAP_SETGID) && gid != ogid && gid_is_valid(gid))
|
||||
if (have_effective_cap(CAP_SETGID) > 0 && gid != ogid && gid_is_valid(gid))
|
||||
r = asprintf(&gid_map,
|
||||
GID_FMT " " GID_FMT " 1\n" /* Map $OGID → $OGID */
|
||||
GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */
|
||||
@ -4669,7 +4669,7 @@ static int exec_child(
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_sandboxing && context->private_users && !have_effective_cap(CAP_SYS_ADMIN)) {
|
||||
if (needs_sandboxing && context->private_users && have_effective_cap(CAP_SYS_ADMIN) <= 0) {
|
||||
/* If we're unprivileged, set up the user namespace first to enable use of the other namespaces.
|
||||
* Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to
|
||||
* set up the all of the other namespaces (i.e. network, mount, UTS) without a user namespace. */
|
||||
|
@ -130,7 +130,7 @@ int kmod_setup(void) {
|
||||
_cleanup_(kmod_unrefp) struct kmod_ctx *ctx = NULL;
|
||||
unsigned i;
|
||||
|
||||
if (have_effective_cap(CAP_SYS_MODULE) == 0)
|
||||
if (have_effective_cap(CAP_SYS_MODULE) <= 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(kmod_table); i++) {
|
||||
|
@ -153,8 +153,12 @@ static int unmerge(void) {
|
||||
}
|
||||
|
||||
static int verb_unmerge(int argc, char **argv, void *userdata) {
|
||||
int r;
|
||||
|
||||
if (!have_effective_cap(CAP_SYS_ADMIN))
|
||||
r = have_effective_cap(CAP_SYS_ADMIN);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if we have enough privileges: %m");
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be privileged.");
|
||||
|
||||
return unmerge();
|
||||
@ -761,7 +765,10 @@ static int verb_merge(int argc, char **argv, void *userdata) {
|
||||
_cleanup_(hashmap_freep) Hashmap *images = NULL;
|
||||
int r;
|
||||
|
||||
if (!have_effective_cap(CAP_SYS_ADMIN))
|
||||
r = have_effective_cap(CAP_SYS_ADMIN);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if we have enough privileges: %m");
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be privileged.");
|
||||
|
||||
r = image_discover_and_read_metadata(&images);
|
||||
@ -796,7 +803,10 @@ static int verb_refresh(int argc, char **argv, void *userdata) {
|
||||
_cleanup_(hashmap_freep) Hashmap *images = NULL;
|
||||
int r;
|
||||
|
||||
if (!have_effective_cap(CAP_SYS_ADMIN))
|
||||
r = have_effective_cap(CAP_SYS_ADMIN);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if we have enough privileges: %m");
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be privileged.");
|
||||
|
||||
r = image_discover_and_read_metadata(&images);
|
||||
|
@ -161,7 +161,7 @@ static void test_drop_privileges_fail(void) {
|
||||
static void test_drop_privileges(void) {
|
||||
fork_test(test_drop_privileges_fail);
|
||||
|
||||
if (have_effective_cap(CAP_NET_RAW) == 0) /* The remaining two tests only work if we have CAP_NET_RAW
|
||||
if (have_effective_cap(CAP_NET_RAW) <= 0) /* The remaining two tests only work if we have CAP_NET_RAW
|
||||
* in the first place. If we are run in some restricted
|
||||
* container environment we might not. */
|
||||
return;
|
||||
@ -171,15 +171,15 @@ static void test_drop_privileges(void) {
|
||||
}
|
||||
|
||||
static void test_have_effective_cap(void) {
|
||||
assert_se(have_effective_cap(CAP_KILL));
|
||||
assert_se(have_effective_cap(CAP_CHOWN));
|
||||
assert_se(have_effective_cap(CAP_KILL) > 0);
|
||||
assert_se(have_effective_cap(CAP_CHOWN) > 0);
|
||||
|
||||
assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_KILL)) >= 0);
|
||||
assert_se(getuid() == test_uid);
|
||||
assert_se(getgid() == test_gid);
|
||||
|
||||
assert_se(have_effective_cap(CAP_KILL));
|
||||
assert_se(!have_effective_cap(CAP_CHOWN));
|
||||
assert_se(have_effective_cap(CAP_KILL) > 0);
|
||||
assert_se(have_effective_cap(CAP_CHOWN) == 0);
|
||||
}
|
||||
|
||||
static void test_update_inherited_set(void) {
|
||||
|
@ -2520,7 +2520,7 @@ static int create_item(Item *i) {
|
||||
|
||||
case CREATE_BLOCK_DEVICE:
|
||||
case CREATE_CHAR_DEVICE:
|
||||
if (have_effective_cap(CAP_MKNOD) == 0) {
|
||||
if (have_effective_cap(CAP_MKNOD) <= 0) {
|
||||
/* In a container we lack CAP_MKNOD. We shouldn't attempt to create the device node in that
|
||||
* case to avoid noise, and we don't support virtualized devices in containers anyway. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user