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.
This commit is contained in:
Christian Göttsche 2021-01-12 11:39:10 +01:00 committed by BenBE
parent 5fde0e0127
commit ceee96dcba
1 changed files with 35 additions and 8 deletions

39
htop.c
View File

@ -115,7 +115,7 @@ static CommandLineSettings parseArguments(int argc, char** argv) {
.highlightChanges = false, .highlightChanges = false,
.highlightDelaySecs = -1, .highlightDelaySecs = -1,
#ifdef HAVE_LIBCAP #ifdef HAVE_LIBCAP
.capabilitiesMode = (geteuid() == 0) ? CAP_MODE_BASIC : CAP_MODE_NONE, .capabilitiesMode = CAP_MODE_BASIC,
#endif #endif
}; };
@ -325,7 +325,7 @@ static int dropCapabilities(enum CapMode mode) {
#endif #endif
}; };
const cap_value_t* const keepcaps = (mode == CAP_MODE_BASIC) ? keepcapsBasic : keepcapsStrict; 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(); cap_t caps = cap_init();
if (caps == NULL) { if (caps == NULL) {
@ -339,24 +339,51 @@ static int dropCapabilities(enum CapMode mode) {
return -1; return -1;
} }
if (cap_set_flag(caps, CAP_PERMITTED, ncap, keepcaps, CAP_SET) < 0) { cap_t currCaps = cap_get_proc();
fprintf(stderr, "Error: can not set permitted capabilities: %s\n", strerror(errno)); if (currCaps == NULL) {
fprintf(stderr, "Error: can not get current process capabilities: %s\n", strerror(errno));
cap_free(caps); cap_free(caps);
return -1; return -1;
} }
if (cap_set_flag(caps, CAP_EFFECTIVE, ncap, keepcaps, CAP_SET) < 0) { for (size_t i = 0; i < ncap; i++) {
fprintf(stderr, "Error: can not set effective capabilities: %s\n", strerror(errno)); if (!CAP_IS_SUPPORTED(keepcaps[i]))
continue;
cap_flag_value_t current;
if (cap_get_flag(currCaps, keepcaps[i], CAP_PERMITTED, &current) < 0) {
fprintf(stderr, "Error: can not get current value of capability %d: %s\n", keepcaps[i], strerror(errno));
cap_free(currCaps);
cap_free(caps); cap_free(caps);
return -1; 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) { if (cap_set_proc(caps) < 0) {
fprintf(stderr, "Error: can not set process capabilities: %s\n", strerror(errno)); fprintf(stderr, "Error: can not set process capabilities: %s\n", strerror(errno));
cap_free(currCaps);
cap_free(caps); cap_free(caps);
return -1; return -1;
} }
cap_free(currCaps);
cap_free(caps); cap_free(caps);
return 0; return 0;