el_*_*gro 5 linux ping linux-capabilities
我从 ping 二进制文件中删除了 setuid 位,并添加了cap_net_raw+p如下内容:
$ chmod 755 /bin/ping
$ setcap cap_net_raw+p /bin/ping
Run Code Online (Sandbox Code Playgroud)
然后我ping在一个终端中运行并从另一个终端检查正在运行的进程的 /proc/$PID/status :
$ 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
Run Code Online (Sandbox Code Playgroud)
如果ping当前正在运行,为什么CapEff: 0000000000000000?不应该cap_net_raw也在有效集中吗?/proc/$PID/status 不反映线程的当前状态吗?
OFTC (irc) 上#kernelnewbies 的一位乐于助人的人很友善地为我提供了答案。
ping设置cap_net_raw为有效集合,创建套接字,然后删除cap_net_raw,如 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
Run Code Online (Sandbox Code Playgroud)
一旦套接字打开,就不再需要任何权限来写入它。