1

From The Linux Programming Interface:

The permitted set is a limiting superset for the capabilities that can be added to the effective and inheritable sets.

Does it mean that the permitted set of a process is a superset of both the effective set and the inheritable set of the process?

The kernel calculates the new capabilities of the process using the following rules:

P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)

P'(effective) = F(effective) ? P'(permitted) : 0

P'(inheritable) = P(inheritable)

In the above rules, P denotes the value of a capability set prior to the exec(), P’ denotes the value of a capability set after the exec(), and F denotes a file capability set. The identifier cap_bset denotes the value of the capability bounding set.

How does the rules guarantee that P'(permitted) is a superset of P'(inheritable)? In other words, can P'(permitted) become not a superset of P(inheritable)?

What does "F(effective) ? P'(permitted) : 0" mean?

Are P(xxx) and F(xxx) sets or bit sets? If latter, are the operations on them bit operations? If former, are the operations on them set operations (union and intersection)?

  • It took me an age to workout what inheritable capabilities could be used for. – ctrl-alt-delor Sep 7 '18 at 10:24
  • I see that you have not accepted an answer. Did you get an acceptable answer?, or do you need more help? – ctrl-alt-delor Dec 23 '18 at 22:53
4

What does "F(effective) ? P'(permitted) : 0" mean?

The expression predicate ? a : b, comes from C like languages. It means a if predicate else b or if the predicate is true it evaluates to a else it evaluates to b.

Therefore P'(effective) = F(effective) ? P'(permitted) : 0 means if the files effective bit is set, then copy the permitted set into the processes effective set, else leave the effective set empty.

This is needed for legacy applications that do-not understand capabilities (probably most at present). A capability aware application, will start with no effective capabilities, and copy capabilities to the effective set when needed, and clear the effective set when done (reducing the harm that bugs can do).

The permitted set is a limiting superset for the capabilities that can be added to the effective and inheritable sets.

You can only add capabilities to the effective or inherited set, if they are in the permitted. However to add a capability to the inherited set, then it must also be in the bounding set. — this paragraph is being discussed in the comments (it may change).

Are P(xxx) and F(xxx) sets or bit sets? If latter, are the operations on them bit operations? If former, are the operations on them set operations (union and intersection)?

Most are bit sets, but F(effective) is a single bit.

You also asked:

How does the rules guarantee that P'(permitted) is a superset of P'(inheritable)? In other words, can P'(permitted) become not a superset of P(inheritable)?

It does not, your statement is a miss reading.

[Permitted] is also a limiting superset for the capabilities that may be added to the inheritable set.

So A process may inherit capabilities to its inherited set, that are not in the permitted set. But may not add a capability to the inherited set, unless it is already in the permitted set.

  • Thanks. I forgot to ask " How does the rules guarantee that P'(permitted) is a superset of P'(inheritable)? In other words, can P'(permitted) become not a superset of P(inheritable)?" – Tim Sep 8 '18 at 4:22
  • @Tim I have now added it to my answer. – ctrl-alt-delor Sep 8 '18 at 14:50
  • Thanks. Is the permitted set a super set of the effective set? – Tim Sep 8 '18 at 15:15
  • " A process may inherit capabilities to its inherited set, that are not in the permitted set", can you give an example, where the inheritable set of a process is not a subset of the permitted set? – Tim Sep 8 '18 at 15:44
  • "You can only add capabilities to the effective or inherited set, if they are in the permitted. However this is not enough. They also need to be in the bounding set." I only found that when adding a capability to inheritable set, the capability must be in both the permitted set and the bounding set. Do you mean it is the same for adding a capability to the effective set? Could you provide the source of citation? – Tim Sep 8 '18 at 16:37
3

The permitted set is a limiting superset for the capabilities that can be added to the effective and inheritable sets.

Does it mean that the permitted set of a process is a superset of both the effective set and the inheritable set of the process?

No, and that statement, while terse, makes no such claim (superset of things that can be added != superset of things that are already there). The inheritable set doesn't have to start out empty.

The capabilities(7) manpage on my system explains it better:

Permitted:
          This is a limiting superset for the effective capabilities  that
          the  thread  may assume.  It is also a limiting superset for the
          capabilities that may be added  to  the  inheritable  set  by  a
          thread  that  does  not  have  the CAP_SETPCAP capability in its
          effective set.

How does the rules guarantee that P'(permitted) is a superset of P'(inheritable)? In other words, can P'(permitted) become not a superset of P(inheritable)?

It does not guarantee such thing. For instance, P'(permitted) will become the empty set (ie not a superset of P(inheritable)) when the thread executes a program with no "security.capability" in the file's extended attribute (ie with empty F(inheritable) and F(permitted)).

What does "P'(effective) = F(effective) ? P'(permitted) : 0" mean?

If F(effective) is not empty, then set P'(effective) to P'(permitted), that is, make all permitted capabilities effective from the start. Since only the empty/non-empty state of F(effective) matters, it's implemented with just a bit/flag in the file's "security.capability" extended attribute.

Are P(xxx) and F(xxx) sets or bit sets?

They're bit sets.

NB: That stuff is a bit outdated; now there is also an ambient capability set which is factored in computing the effective set. Check the capabilities(7) manpage on any newer system.

  • Thanks. I forgot to ask " How does the rules guarantee that P'(permitted) is a superset of P'(inheritable)? In other words, can P'(permitted) become not a superset of P(inheritable)?" – Tim Sep 8 '18 at 4:23
  • Thanks. " P'(permitted) will become the empty set (ie not a superset of P(inheritable)) when the thread executes a program with no "security.capability" in the file's extended attribute (ie with an empty F(inheritable))." But P'(permitted) also includes "(F(permitted) & cap_bset)", so how do you know P'(permitted) will become empty? By " a program with no "security.capability" in the file's extended attribute", do you mean both F(permitted) and F(inheritable) are empty? – Tim Sep 8 '18 at 15:48
  • Yes. All file sets are stored in a single extended attribute, 'security.capability', so exec'ing a file with no such attribute will drop all caps to 0. Most binaries do NOT have such an attribute, the only use of it that I found in the wild was /bin/ping with F(permitted)==NET_RAW and F(effective)== 1 in order to be able to open a raw socket without being setuid. I haven't seen any program making use of the inheritable caps mechanism. Please read the lkml discussion I've pointed to for better (and less formal) explanation of the whole capability mess, and their attempts to fix it. – mosvy Sep 9 '18 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.