Jouni
Jouni

Reputation: 413

why keep-caps is not activated by capsh

I'm trying to come up with capsh invokation that would use keep-caps feature. I expected the following to work, since I'm passing the --keep=1 flag

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

Contrary to what I though the following output is produced by the first --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)

and by the second --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)

Questions:

Upvotes: 1

Views: 135

Answers (1)

Andrew G Morgan
Andrew G Morgan

Reputation: 394

The capsh tool executes its command line arguments in strict order. The --user=$(whoami) argument (I think you missed the $ bit), lowers all of the effective bits (see man capsh) by the time it completes. It, however, preserves all of the Permitted bits, so you can use/raise them in later arguments. Try this:

$ sudo -E capsh --user=$(whoami) \
  --caps="cap_setgid+pei cap_setuid+pei cap_setpcap+pei cap_dac_override+pei" \
  --addamb="cap_dac_override" --print \
  == --print

Note, I've not used the --keep=1 at all here. That being said, (see man capsh again), to answer your --keep=1 question when the == argument is acted on, one of the exec*() functions is performed and that will reset the secure-keep-caps values back to zero.

The p bits are not Inheritable bits, they are never passed through exec. The only bits that are inherited through exec are the IAB bits. If you want to dive into all the details, I wrote a long article about how inheritance works on the libcap distribution website.

Upvotes: 1

Related Questions