5

I am having a difficult time understanding how capabilities are inherited. It is possible there is no such thing as "capability inheritance" and that I have completely misunderstood this documentation:

https://man7.org/linux/man-pages/man7/capabilities.7.html

So I may need help re-orienting my entire understanding of what linux capabilities are!

In terms of how I tried to understand capability inheritance, here is the experiment I ran:

bob@bob:~$ getcap /bin/bash # show no capabilities
bob@bob:~$ getpcaps $$ # shows no capabilities
2076: =
bob@bob:~$ sudo cp /bin/bash /usr/local/bin/testing_bash # let's make a copy of bash and give it all capabilities
bob@bob:~$ sudo setcap all=eip /usr/local/bin/testing_bash # giving all capabilities
bob@bob:~$ getcap /usr/local/bin/testing_bash # shows all capabilities
/usr/local/bin/testing_bash =eip
bob@bob:~$ /usr/local/bin/testing_bash # run bash with same capabilities as root
bob@bob:~$ getpcaps $$ # confirmed I have same capabilities as root
2092: =ep
bob@bob:~$ mkdir hello
bob@bob:~$ mount -t tmpfs test hello
mount: /home/bob/helloworld: must be superuser to use mount.

Basically I copied the bash command to testing_bash and gave it all capabilities so that I can run it as if i were root user. I run the testing_bash and confirmed that I do have all the escalated capabilities. But when I run the mount command later, it did not inherit my escalated capabilities, and instead I get a permission error.

I tried reading this link here but I fail to comprehend:

https://man7.org/linux/man-pages/man7/capabilities.7.html

Specifically the line on Inheritable. I thought if I add the letter i to eip in the setcap all=eip, that means all child processes will inherit the capabilities of /usr/local/bin/testing_bash?

I repeated a similar experiment with the User Namespace and still encountered the same capabilities error:

bob@bob:~$ unshare -U /usr/local/bin/testing_bash
nobody@bob:~$ getpcaps $$
2123: =ep
nobody@bob:~$ unshare -m /bin/bash
unshare: unshare failed: Operation not permitted

In other words, I start a new namespace with the testing_bash, confirmed I have all capabilities, but running the unshare command gives a capabilities/permission error.

So my question is, have I mis-understood how capability inheritance works?


I am very new to learning about linux in general and linux capabilities. It's possible my question above is related to these two other questions I asked recently:

Can a non-zero (not 0, not root) user run a process with capabilities `[pid]: =ep`?

How come `setcap all=eip` has fewer capabilities than `setcap cap_sys_admin=eip`?

1 Answer 1

1

There are two kinds of capabilities supported by the Linux kernel:

  • Two that are not inheritable: Permitted and Effective sets.
  • Three that are inheritable: Inheritable set, Bounding and Ambient vectors.

The only capabilities that represent privilege are the Permitted and the Effective ones. The Effective set is limited to being equal to, or a sub-set of the Permitted set. The others are used to influence the way the Permitted set is changed.

The libcap library and associated tools group these into two representations: the capability Set (eip) and the IAB-tuple (iab). Yes, the Inheritable Set/Vector is present in both.

You can use the Inheritable set to coax a binary that has been given an Inheritable file capability to enable it in its Permitted set by exec'ing it from a program with an Inheritable capability:

$ cp /sbin/capsh ./mycapsh
$ sudo /sbin/setcap cap_setuid=i ./mycapsh
$ sudo /sbin/capsh --inh=cap_setuid --user=$(whoami) == --current --
Current: cap_setuid=i
Current IAB: cap_setuid
$ ./mycapsh --current
Current: cap_setuid=ip
Current IAB: cap_setuid
$ exit
$ ./mycapsh --current
Current: =
Current IAB: 
$ 

These kinds of file capabilities enable specific binaries to leverage Inheritable capabilities, but not regular programs unprepared to be privileged.

You can use the Ambient vector to naively pass on capabilities from a parent to any child program (that doesn't have file capabilities on it):

$ sudo /sbin/setcap = ./mycapsh
$ /sbin/getcap ./mycapsh 
./mycapsh =
$ sudo /sbin/capsh --user=$(whoami) --iab='^cap_setuid' == --current --
Current: cap_setuid=eip
Current IAB: ^cap_setuid
$ ./mycapsh --current
Current: cap_setuid=i
Current IAB: cap_setuid
$ 

Here, ./mycapsh has forced empty file capabilities to prevent the Ambient inheritance from working. However, the Inheritable set (which isn't considered privilege, as noted above) continues to be inherited.

If we clear that (empty) file capability (by overwriting the ./mycapsh file) and try again the Ambient capability caused the Permitted capability to be inherited:

$ cp /sbin/capsh ./mycapsh 
$ /sbin/getcap mycapsh 
$ ./mycapsh --current
Current: cap_setuid=eip
Current IAB: ^cap_setuid
$ exit
$ ./mycapsh --current
Current: =
Current IAB:
$ 
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.