I removed the setuid bit from the ping binary and added cap_net_raw+p
instead as follows:
$ chmod 755 /bin/ping
$ setcap cap_net_raw+p /bin/ping
Then I ran ping
in one terminal and checked the /proc/$PID/status of the running process from another:
$ ps aux | grep ping
user 5468 0.0 0.0 14948 1792 pts/20 S+ 11:14 0:00 ping www.google.com
user 5471 0.0 0.0 14224 896 pts/2 S+ 11:14 0:00 grep --color=auto ping
$ cat /proc/5468/status | grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000002000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
If ping
is currently running why is CapEff: 0000000000000000
? Shouldn't cap_net_raw
be in the effective set as well? Does /proc/$PID/status not reflect the current state of the thread?
A helpful person in #kernelnewbies on OFTC (irc) was kind enough to provide me with the answer.
ping
sets cap_net_raw
in the effective set, creates the socket, then drops cap_net_raw
, as can been seen with strace:
$ strace -e socket,capset ping -c1 localhost
capset({_LINUX_CAPABILITY_VERSION_3, 0}, {CAP_NET_RAW, CAP_NET_ADMIN|CAP_NET_RAW, 0}) = 0
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
capset({_LINUX_CAPABILITY_VERSION_3, 0}, {0, CAP_NET_ADMIN|CAP_NET_RAW, 0}) = 0
Once the socket is open, no more privileges are required to write to it.
来源:https://stackoverflow.com/questions/46059187/why-is-capeff-all-zeros-in-proc-pid-status