diff --git a/lib/utils.c b/lib/utils.c index 8a0bff0b..7b2c6dd1 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1612,14 +1612,23 @@ void drop_cap(void) /* don't harmstring root/sudo */ if (getuid() != 0 && geteuid() != 0) { cap_t capabilities; + cap_value_t net_admin = CAP_NET_ADMIN; + cap_flag_t inheritable = CAP_INHERITABLE; + cap_flag_value_t is_set; capabilities = cap_get_proc(); if (!capabilities) exit(EXIT_FAILURE); - if (cap_clear(capabilities) != 0) - exit(EXIT_FAILURE); - if (cap_set_proc(capabilities) != 0) + if (cap_get_flag(capabilities, net_admin, inheritable, + &is_set) != 0) exit(EXIT_FAILURE); + /* apps with ambient caps can fork and call ip */ + if (is_set == CAP_CLEAR) { + if (cap_clear(capabilities) != 0) + exit(EXIT_FAILURE); + if (cap_set_proc(capabilities) != 0) + exit(EXIT_FAILURE); + } cap_free(capabilities); } #endif diff --git a/man/man8/ip-vrf.8 b/man/man8/ip-vrf.8 index 1a42cebe..c1c9b958 100644 --- a/man/man8/ip-vrf.8 +++ b/man/man8/ip-vrf.8 @@ -70,6 +70,10 @@ This command also requires to be ran as root or with the CAP_SYS_ADMIN, CAP_NET_ADMIN and CAP_DAC_OVERRIDE capabilities. If built with libcap and if capabilities are added to the ip binary program via setcap, the program will drop them as the first thing when invoked, unless the command is vrf exec. +.br +NOTE: capabilities will NOT be dropped if CAP_NET_ADMIN is set to INHERITABLE +to avoid breaking programs with ambient capabilities that call ip. +Do not set the INHERITABLE flag on the ip binary itself. .TP .B ip vrf identify [PID] - Report VRF association for process