Bug 2120843

Summary: openssh: ambient capabilities failed to applied to non-root user even when correct rules are in /etc/security/capability.conf
Product: Red Hat Enterprise Linux 8 Reporter: Chris Cheney <ccheney>
Component: opensshAssignee: Zoltan Fridrich <zfridric>
Status: CLOSED WONTFIX QA Contact: Marek Havrila <mhavrila>
Severity: medium Docs Contact:
Priority: medium    
Version: 8.6CC: hartsjc, jjelen, mhavrila, zfridric
Target Milestone: rcKeywords: Triaged
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-02-17 14:45:06 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Chris Cheney 2022-08-23 21:08:53 UTC
openssh does not keep ambient capabilities applied to non-root users

   Note: This same issue also affects RHEL 9 and Fedora 36

This issue appears to be similar to bug in su (util-linux) bz 1950187 that was fixed in util-linux 2.32.1-31

   util-linux:

   * Tue Jan 11 2022 Karel Zak <kzak> 2.32.1-31
   - improve #2026511 fix - blkid fails to complete when targeting non-block devices
   - fix #1950187 - Ambient capabilities failed to applied to non-root user

To reproduce:

Setup pam_cap.so and /etc/security/capability.conf to allow a non-root user to have one or more capabilities.

   line to add for pam_cap.so:

   auth        optional                   pam_cap.so debug keepcaps

   or

   auth        optional                   pam_cap.so debug keepcaps defer

   Note: It probably should work with either setting above, but currently is broken in different ways depending on which you have set.

Example /etc/security/capability.conf file:

   ^cap_net_raw,^cap_sys_nice,^cap_sys_ptrace,^cap_syslog,^cap_perfmon ccheney
   none *

Broken output looks like:

   $ capsh --print
   Current: cap_net_raw,cap_sys_ptrace,cap_sys_nice,cap_syslog,cap_perfmon=i

or this:

   $ capsh --print
   Current: =

Correct output should look like:

   $ capsh --print
   Current: cap_net_raw,cap_sys_ptrace,cap_sys_nice,cap_syslog,cap_perfmon=eip

It appears that openssh likely causes the capabilities to go away when it set uid to the user, as happened with 'su'.

The following links go into a bit more detail about the issue specific to 'su'.

   Bug 212945 - pam_cap not working with su for ambient setting
   https://bugzilla.kernel.org/show_bug.cgi?id=212945

   Add support for ambient capabilities #408
   https://github.com/shadow-maint/shadow/pull/408#issuecomment-919673098


----

Strace from a test ssh session with capabilities set for the user logging in (without defer set):


4678  12:42:48.168017 sendto(3<UNIX:[79491->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug1: restore_uid: 0/0", 56, MSG_NOSIGNAL, NULL, 0) = 56 <0.000048>
4678  12:42:48.168278 sendto(3<UNIX:[79495->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug1: SELinux support enabled", 63, MSG_NOSIGNAL, NULL, 0) = 63 <0.000047>
4678  12:42:48.168498 sendto(3<UNIX:[79499->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug3: sshd_selinux_setup_variables: setting execution context", 95, MSG_NOSIGNAL, NULL, 0) = 95 <0.000050>
4678  12:42:48.168844 sendto(3<UNIX:[79503->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug1: PAM: establishing credentials", 69, MSG_NOSIGNAL, NULL, 0) = 69 <0.000046>

<...>

4678  12:42:48.171679 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) = 0 <0.000002>
4678  12:42:48.171697 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_OVERRIDE, 0, 0) = 0 <0.000002>
4678  12:42:48.171709 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_READ_SEARCH, 0, 0) = 0 <0.000002>
4678  12:42:48.171720 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FOWNER, 0, 0) = 0 <0.000002>
4678  12:42:48.171732 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FSETID, 0, 0) = 0 <0.000002>
4678  12:42:48.171743 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_KILL, 0, 0) = 0 <0.000002>
4678  12:42:48.171754 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETGID, 0, 0) = 0 <0.000002>
4678  12:42:48.171765 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETUID, 0, 0) = 0 <0.000002>
4678  12:42:48.171776 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETPCAP, 0, 0) = 0 <0.000002>
4678  12:42:48.171787 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_LINUX_IMMUTABLE, 0, 0) = 0 <0.000002>
4678  12:42:48.171798 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0) = 0 <0.000002>
4678  12:42:48.171810 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BROADCAST, 0, 0) = 0 <0.000002>
4678  12:42:48.171821 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_ADMIN, 0, 0) = 0 <0.000002>
4678  12:42:48.171832 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_RAW, 0, 0) = 0 <0.000002>
4678  12:42:48.171843 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_IPC_LOCK, 0, 0) = 0 <0.000002>
4678  12:42:48.171854 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_IPC_OWNER, 0, 0) = 0 <0.000002>
4678  12:42:48.171865 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_MODULE, 0, 0) = 0 <0.000002>
4678  12:42:48.171876 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_RAWIO, 0, 0) = 0 <0.000002>
4678  12:42:48.171887 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_CHROOT, 0, 0) = 0 <0.000002>
4678  12:42:48.171898 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_PTRACE, 0, 0) = 0 <0.000002>
4678  12:42:48.171909 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_PACCT, 0, 0) = 0 <0.000002>
4678  12:42:48.171920 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_ADMIN, 0, 0) = 0 <0.000002>
4678  12:42:48.171931 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_BOOT, 0, 0) = 0 <0.000002>
4678  12:42:48.171942 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_NICE, 0, 0) = 0 <0.000002>
4678  12:42:48.171954 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_RESOURCE, 0, 0) = 0 <0.000002>
4678  12:42:48.171965 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_TIME, 0, 0) = 0 <0.000002>
4678  12:42:48.171976 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYS_TTY_CONFIG, 0, 0) = 0 <0.000002>
4678  12:42:48.171987 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_MKNOD, 0, 0) = 0 <0.000002>
4678  12:42:48.171998 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_LEASE, 0, 0) = 0 <0.000002>
4678  12:42:48.172009 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_AUDIT_WRITE, 0, 0) = 0 <0.000002>
4678  12:42:48.172020 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_AUDIT_CONTROL, 0, 0) = 0 <0.000002>
4678  12:42:48.172031 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETFCAP, 0, 0) = 0 <0.000002>
4678  12:42:48.172042 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_MAC_OVERRIDE, 0, 0) = 0 <0.000002>
4678  12:42:48.172053 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_MAC_ADMIN, 0, 0) = 0 <0.000002>
4678  12:42:48.172064 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SYSLOG, 0, 0) = 0 <0.000002>
4678  12:42:48.172078 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_WAKE_ALARM, 0, 0) = 0 <0.000002>
4678  12:42:48.172089 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_BLOCK_SUSPEND, 0, 0) = 0 <0.000002>
4678  12:42:48.172100 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_AUDIT_READ, 0, 0) = 0 <0.000002>
4678  12:42:48.172111 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_PERFMON, 0, 0) = 0 <0.000002>
4678  12:42:48.172122 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_BPF, 0, 0) = 0 <0.000002>
4678  12:42:48.172133 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHECKPOINT_RESTORE, 0, 0) = 0 <0.000002>
4678  12:42:48.172144 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0x29 /* CAP_??? */, 0, 0) = -1 EINVAL (Invalid argument) <0.000002>

4678  12:42:48.172159 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_PERFMON, 0, 0) = 0 <0.000003>
4678  12:42:48.172172 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYSLOG, 0, 0) = 0 <0.000002>
4678  12:42:48.172184 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYS_NICE, 0, 0) = 0 <0.000002>
4678  12:42:48.172196 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYS_PTRACE, 0, 0) = 0 <0.000002>
4678  12:42:48.172208 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0) = 0 <0.000002>

4678  12:42:48.172220 capset({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, permitted=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, inheritable=1<<CAP_NET_RAW|1<<CAP_SYS_PTRACE|1<<CAP_SYS_NICE|1<<CAP_SYSLOG|1<<CAP_PERFMON}) = 0 <0.000003>

4678  12:42:48.172240 prctl(PR_SET_KEEPCAPS, 1) = 0 <0.000002>

<...>

4678  12:42:48.176731 sendto(3<UNIX:[79540->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug3: PAM: opening session", 60, MSG_NOSIGNAL, NULL, 0) = 60 <0.000055>
4678  12:42:48.177015 sendto(3<UNIX:[79544->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug2: do_pam_session: auth information in SSH_AUTH_INFO_0", 91, MSG_NOSIGNAL, NULL, 0) = 91 <0.000049>
4678  12:42:48.184258 sendto(7<UNIX:[79754->13606]>, "<87>Aug 23 12:42:48 sshd[4678]: debug3: PAM: sshpam_store_conv called with 1 messages", 85, MSG_NOSIGNAL, NULL, 0) = 85 <0.000057>
4678  12:42:48.345985 sendto(3<UNIX:[80357->13606]>, "<86>Aug 23 12:42:48 sshd[4678]: pam_unix(sshd:session): session opened for user ccheney by (uid=0)", 98, MSG_NOSIGNAL, NULL, 0) = 98 <0.000070>
4678  12:42:48.352204 sendto(3<UNIX:[80357->13606]>, "<86>Aug 23 12:42:48 sshd[4678]: User child is on pid 4712", 57, MSG_NOSIGNAL, NULL, 0) = 57 <0.000097>
4712  12:42:48.373340 sendto(3<UNIX:[80357->13606]>, "<87>Aug 23 12:42:48 sshd[4712]: debug1: PAM: establishing credentials", 69, MSG_NOSIGNAL, NULL, 0) = 69 <0.000342>

<...>

4712  12:42:48.374069 capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, NULL) = 0 <0.000002>

4712  12:42:48.374084 capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, permitted=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, inheritable=1<<CAP_NET_RAW|1<<CAP_SYS_PTRACE|1<<CAP_SYS_NICE|1<<CAP_SYSLOG|1<<CAP_PERFMON}) = 
0 <0.000002>

4712  12:42:48.376803 capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, NULL) = 0 <0.000002>

4712  12:42:48.376820 capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, permitted=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, inheritable=1<<CAP_NET_RAW|1<<CAP_SYS_PTRACE|1<<CAP_SYS_NICE|1<<CAP_SYSLOG|1<<CAP_PERFMON}) = 0 <0.000002>

4712  12:42:48.376838 capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, NULL) = 0 <0.000002>

4712  12:42:48.376852 capset({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, permitted=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, inheritable=1<<CAP_NET_RAW|1<<CAP_SYS_PTRACE|1<<CAP_SYS_NICE|1<<CAP_SYSLOG|1<<CAP_PERFMON}) = 
0 <0.000093>

4712  12:42:48.376967 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) = 0 <0.000003>
4712  12:42:48.376984 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_OVERRIDE, 0, 0) = 0 <0.000002>
4712  12:42:48.376996 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_DAC_READ_SEARCH, 0, 0) = 0 <0.000002>
4712  12:42:48.377008 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FOWNER, 0, 0) = 0 <0.000002>
4712  12:42:48.377019 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_FSETID, 0, 0) = 0 <0.000002>
4712  12:42:48.377031 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_KILL, 0, 0) = 0 <0.000002>
4712  12:42:48.377042 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETGID, 0, 0) = 0 <0.000002>
4712  12:42:48.377056 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETUID, 0, 0) = 0 <0.000002>
4712  12:42:48.377068 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_SETPCAP, 0, 0) = 0 <0.000002>
4712  12:42:48.377079 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_LINUX_IMMUTABLE, 0, 0) = 0 <0.000002>
4712  12:42:48.377090 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BIND_SERVICE, 0, 0) = 0 <0.000002>
4712  12:42:48.377102 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_BROADCAST, 0, 0) = 0 <0.000002>
4712  12:42:48.377113 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_ADMIN, 0, 0) = 0 <0.000002>
4712  12:42:48.377125 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_RAW, 0, 0) = 1 <0.000002>

4712  12:42:48.377136 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) = 0 <0.000003>

<.. Here it is setting the ambient flag for the capabilities listed in the file ...>

4712  12:42:48.377149 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_PERFMON, 0, 0) = 0 <0.000002>
4712  12:42:48.377162 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYSLOG, 0, 0) = 0 <0.000002>
4712  12:42:48.377174 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYS_NICE, 0, 0) = 0 <0.000002>
4712  12:42:48.377186 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_SYS_PTRACE, 0, 0) = 0 <0.000002>
4712  12:42:48.377198 prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0) = 0 <0.000002>

4712  12:42:48.377211 capset({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, permitted=1<<CAP_CHOWN|1<<CAP_DAC_OVERRIDE|1<<CAP_DAC_READ_SEARCH|1<<CAP_FOWNER|1<<CAP_FSETID|1<<CAP_KILL|1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_LINUX_IMMUTABLE|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_BROADCAST|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_IPC_LOCK|1<<CAP_IPC_OWNER|1<<CAP_SYS_MODULE|1<<CAP_SYS_RAWIO|1<<CAP_SYS_CHROOT|1<<CAP_SYS_PTRACE|1<<CAP_SYS_PACCT|1<<CAP_SYS_ADMIN|1<<CAP_SYS_BOOT|1<<CAP_SYS_NICE|1<<CAP_SYS_RESOURCE|1<<CAP_SYS_TIME|1<<CAP_SYS_TTY_CONFIG|1<<CAP_MKNOD|1<<CAP_LEASE|1<<CAP_AUDIT_WRITE|1<<CAP_AUDIT_CONTROL|1<<CAP_SETFCAP|1<<CAP_MAC_OVERRIDE|1<<CAP_MAC_ADMIN|1<<CAP_SYSLOG|1<<CAP_WAKE_ALARM|1<<CAP_BLOCK_SUSPEND|1<<CAP_AUDIT_READ|1<<CAP_PERFMON|1<<CAP_BPF|1<<CAP_CHECKPOINT_RESTORE, inheritable=1<<CAP_NET_RAW|1<<CAP_SYS_PTRACE|1<<CAP_SYS_NICE|1<<CAP_SYSLOG|1<<CAP_PERFMON}) = 0 <0.000003>

4712  12:42:48.377231 prctl(PR_SET_KEEPCAPS, 1) = 0 <0.000002>


<... this is likely where it breaks, as it setuid after setting ambient ...>

4712  12:42:48.380605 sendto(3<UNIX:[80494->13606]>, "<87>Aug 23 12:42:48 sshd[4712]: debug3: sshd_selinux_setup_variables: setting execution context", 95, MSG_NOSIGNAL, NULL, 0) = 95 <0.000079>
4712  12:42:48.380984 sendto(3<UNIX:[80498->13606]>, "<87>Aug 23 12:42:48 sshd[4712]: debug1: permanently_set_uid: 1000/1000", 70, MSG_NOSIGNAL, NULL, 0) = 70 <0.000053>

Comment 9 Zoltan Fridrich 2023-02-17 14:45:06 UTC
I will be closing this bug as "WONTFIX".

The reason is that pam_cap module is not part of the standard PAM configuration for sshd,
the module tries to surpass security measures of openssh and linux kernel and overall is
not compatible with fundamental design of openssh. Therefore pam_cap module should not
be considered compatible with openssh.

To workaround this bug user can use su binary to su to himself to gain the capabilities
after using ssh. One option would be to create a custom shell binary that would run shell,
than self-su.

Here is a simple workaround demo using su:

1. # useradd testuser
2. # passwd testuser
3. # sed -i '1i auth optional pam_cap.so keepcaps defer' /etc/pam.d/su
4. # echo '^cap_chown *' > /etc/security/capability.conf
5. # ssh -l testuser localhost
6. # su testuser
7. $ grep Cap /proc/$$/status

CapInh: 0000000000000001
CapPrm: 0000000000000001
CapEff: 0000000000000001
CapBnd: 000001ffffffffff
CapAmb: 0000000000000001