diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2021-01-12 11:39:10 +0100 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2021-01-13 22:12:06 +0100 |
commit | ceee96dcba7d4932d1ec4d9a745a572c47c43c1d (patch) | |
tree | 3a31a8a3ca86c99cf0e3b624f4995aff08ab30e8 | |
parent | 5fde0e012762b07e4955306b743afcf43fe237c6 (diff) |
Do not try to set not owned capabilities
If the process has already less capabilities than we are trying to keep,
do not try to set them.
-rw-r--r-- | htop.c | 43 |
1 files changed, 35 insertions, 8 deletions
@@ -115,7 +115,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) { .highlightChanges = false, .highlightDelaySecs = -1, #ifdef HAVE_LIBCAP - .capabilitiesMode = (geteuid() == 0) ? CAP_MODE_BASIC : CAP_MODE_NONE, + .capabilitiesMode = CAP_MODE_BASIC, #endif }; @@ -325,7 +325,7 @@ static int dropCapabilities(enum CapMode mode) { #endif }; const cap_value_t* const keepcaps = (mode == CAP_MODE_BASIC) ? keepcapsBasic : keepcapsStrict; - const int ncap = (mode == CAP_MODE_BASIC) ? ARRAYSIZE(keepcapsBasic) : ARRAYSIZE(keepcapsStrict); + const size_t ncap = (mode == CAP_MODE_BASIC) ? ARRAYSIZE(keepcapsBasic) : ARRAYSIZE(keepcapsStrict); cap_t caps = cap_init(); if (caps == NULL) { @@ -339,24 +339,51 @@ static int dropCapabilities(enum CapMode mode) { return -1; } - if (cap_set_flag(caps, CAP_PERMITTED, ncap, keepcaps, CAP_SET) < 0) { - fprintf(stderr, "Error: can not set permitted capabilities: %s\n", strerror(errno)); + cap_t currCaps = cap_get_proc(); + if (currCaps == NULL) { + fprintf(stderr, "Error: can not get current process capabilities: %s\n", strerror(errno)); cap_free(caps); return -1; } - if (cap_set_flag(caps, CAP_EFFECTIVE, ncap, keepcaps, CAP_SET) < 0) { - fprintf(stderr, "Error: can not set effective capabilities: %s\n", strerror(errno)); - cap_free(caps); - return -1; + for (size_t i = 0; i < ncap; i++) { + if (!CAP_IS_SUPPORTED(keepcaps[i])) + continue; + + cap_flag_value_t current; + if (cap_get_flag(currCaps, keepcaps[i], CAP_PERMITTED, ¤t) < 0) { + fprintf(stderr, "Error: can not get current value of capability %d: %s\n", keepcaps[i], strerror(errno)); + cap_free(currCaps); + cap_free(caps); + return -1; + } + + if (current != CAP_SET) + continue; + + if (cap_set_flag(caps, CAP_PERMITTED, 1, &keepcaps[i], CAP_SET) < 0) { + fprintf(stderr, "Error: can not set permitted capability %d: %s\n", keepcaps[i], strerror(errno)); + cap_free(currCaps); + cap_free(caps); + return -1; + } + + if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &keepcaps[i], CAP_SET) < 0) { + fprintf(stderr, "Error: can not set effective capability %d: %s\n", keepcaps[i], strerror(errno)); + cap_free(currCaps); + cap_free(caps); + return -1; + } } if (cap_set_proc(caps) < 0) { fprintf(stderr, "Error: can not set process capabilities: %s\n", strerror(errno)); + cap_free(currCaps); cap_free(caps); return -1; } + cap_free(currCaps); cap_free(caps); return 0; |