mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-28 06:35:34 +07:00
execute: when we run as PID 1 the kernel doesn't give us CAP_SETPCAP by default. Get that temporarily when dropping capabilities for good
This commit is contained in:
parent
8024c3a71a
commit
73090dc815
11
TODO
11
TODO
@ -32,8 +32,16 @@ F15:
|
||||
* don't trim empty cgroups
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=678555
|
||||
|
||||
* drop cap bounding set in logger, hostnamed, readahead, ...
|
||||
|
||||
* timeout value is incorrectly parsed in /etc/fstab
|
||||
|
||||
Features:
|
||||
|
||||
* Add ListenSpecial to .socket units for /proc/kmsg and similar friends?
|
||||
|
||||
* avoid DefaultStandardOutput=syslog to have any effect on StandardInput=socket services
|
||||
|
||||
* use pivot_root on shutdown so that we can unmount the root directory.
|
||||
|
||||
* fix alsa mixer restore to not print error when no config is stored
|
||||
@ -43,8 +51,11 @@ Features:
|
||||
* write blog stories about:
|
||||
- enabling dbus services
|
||||
- status update
|
||||
- the new configuration files
|
||||
- you are a distro: why switch?
|
||||
|
||||
* maybe add tiny dbus services similar to hostnamed for locale?
|
||||
|
||||
* allow port = 0 in .socket units
|
||||
|
||||
* rename systemd-logger to systemd-stdio-syslog-bridge
|
||||
|
@ -904,6 +904,68 @@ fail:
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_capability_bounding_set_drop(uint64_t drop) {
|
||||
unsigned long i;
|
||||
cap_t old_cap = NULL, new_cap = NULL;
|
||||
cap_flag_value_t fv;
|
||||
int r;
|
||||
|
||||
/* If we are run as PID 1 we will lack CAP_SETPCAP by default
|
||||
* in the effective set (yes, the kernel drops that when
|
||||
* executing init!), so get it back temporarily so that we can
|
||||
* call PR_CAPBSET_DROP. */
|
||||
|
||||
old_cap = cap_get_proc();
|
||||
if (!old_cap)
|
||||
return -errno;
|
||||
|
||||
if (cap_get_flag(old_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (fv != CAP_SET) {
|
||||
static const cap_value_t v = CAP_SETPCAP;
|
||||
|
||||
new_cap = cap_dup(old_cap);
|
||||
if (!new_cap) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (cap_set_flag(new_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (cap_set_proc(new_cap) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= CAP_LAST_CAP; i++)
|
||||
if (drop & ((uint64_t) 1ULL << (uint64_t) i)) {
|
||||
if (prctl(PR_CAPBSET_DROP, i) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
if (new_cap)
|
||||
cap_free(new_cap);
|
||||
|
||||
if (old_cap) {
|
||||
cap_set_proc(old_cap);
|
||||
cap_free(old_cap);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int exec_spawn(ExecCommand *command,
|
||||
char **argv,
|
||||
const ExecContext *context,
|
||||
@ -1251,13 +1313,10 @@ int exec_spawn(ExecCommand *command,
|
||||
}
|
||||
|
||||
if (context->capability_bounding_set_drop)
|
||||
for (i = 0; i <= CAP_LAST_CAP; i++)
|
||||
if (context->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i)) {
|
||||
if (prctl(PR_CAPBSET_DROP, i) < 0) {
|
||||
r = EXIT_CAPABILITIES;
|
||||
goto fail_child;
|
||||
}
|
||||
}
|
||||
if (do_capability_bounding_set_drop(context->capability_bounding_set_drop) < 0) {
|
||||
r = EXIT_CAPABILITIES;
|
||||
goto fail_child;
|
||||
}
|
||||
|
||||
if (context->user)
|
||||
if (enforce_user(context, uid) < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user