capsh的keep-caps特性未生效及相关能力问题咨询
capsh keep-caps特性使用疑问与解析
我尝试编写调用capsh并利用keep-caps特性的命令,已传入--keep=1参数,预期生效的命令如下:
sudo -E capsh \ --caps="cap_setgid+pei cap_setuid+pei cap_setpcap+pei cap_dac_override+pei" \ --user=$(whoami) --keep=1 \ --addamb="cap_dac_override" --print \ == --print
但实际输出与预期不符,第一个--print的输出如下:
Current: cap_dac_override,cap_setgid,cap_setuid,cap_setpcap=ip Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore Ambient set =cap_dac_override Current IAB: ^cap_dac_override,cap_setgid,cap_setuid,cap_setpcap Securebits: 020/0x10/5'b10000 (no-new-privs=0) secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: yes (unlocked) secure-no-ambient-raise: no (unlocked) uid=1000(jouni) euid=1000(jouni) gid=100(users) groups=1(wheel),57(networkmanager),100(users),174(input) Guessed mode: UNCERTAIN (0)
第二个--print的输出如下:
Current: cap_dac_override=eip cap_setgid,cap_setuid,cap_setpcap+i Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore Ambient set =cap_dac_override Current IAB: ^cap_dac_override,cap_setgid,cap_setuid,cap_setpcap Securebits: 00/0x0/1'b0 (no-new-privs=0) secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: no (unlocked) secure-no-ambient-raise: no (unlocked) uid=1000(jouni) euid=1000(jouni) gid=100(users) groups=1(wheel),57(networkmanager),100(users),174(input) Guessed mode: HYBRID (4)
技术问询
- 为何第一个
--print的Current字段中仅存在=ip的能力,e位能力去向何处? - 为何secure-keep-caps从yes变为no?
--keep=1参数不应使其保持yes吗?如何让它保持yes? - 为何最后一个
--print中仍存在i位能力?若p位已被丢弃,i位为何保留?
解答
关于e位能力消失的问题
第一个--print是在capsh完成用户切换(--user=$(whoami))后输出的。当从root切换到普通用户时,内核会自动清除有效能力(e位),这是内核的安全机制——防止root的有效能力被普通用户直接继承。即便secure-keep-caps设置为yes,也仅能保留允许位(p)和继承位(i),有效位仍会被重置。关于secure-keep-caps变为no的问题
--keep=1仅对capsh自身处理用户切换的阶段生效,当使用==分隔符启动新进程(第二个capsh --print)时,默认情况下execve系统调用会重置secure-keep-caps位。要让该属性保持yes,需要添加--no-new-privs参数,该参数会阻止execve重置进程的安全属性,修改后的命令如下:
sudo -E capsh \ --caps="cap_setgid+pei cap_setuid+pei cap_setpcap+pei cap_dac_override+pei" \ --user=$(whoami) --keep=1 --no-new-privs \ --addamb="cap_dac_override" --print \ == --print
- 关于i位能力保留的问题
允许位(p)控制当前进程可以主动使用的能力集合,而继承位(i)控制进程fork出的子进程可以继承的能力集合,二者是独立的控制位。当secure-keep-caps被重置为no后,内核仅会清除允许位(p),但继承位(i)不受此影响——只要能力仍在Bounding set中,继承位就会保留,除非被显式清除。这是Linux能力模型的设计规则。
内容的提问来源于stack exchange,提问作者Jouni
相关产品推荐
相关产品推荐

