4

man 7 capabilities documents that the capabilities of a process on a linux box are recored a set of three masks:

  • permitted
  • effective
  • inheritable

I have an idea to what extend the inheritable mask would come to play but I am unclear about why there seems to be a need/use case to separate capabilities that are permitted from those that are effective?

Is there a case that some permitted capabilities are not effective? which could spice up an answer to this question?

Bonus round

Given the case some Capabilities are not effective and yet permitted, what keeps a process from setting them effective? It would seem to me at least that a rougue process would not hesitate to set all what is permitted as effetive, and normaly even attempt to escalate priveledges further?

3

Quick hypothetical where it could be useful: You want a user to be able to copy (read) any file on the system, but not change (write) to them. You could have a program that has CAP_DAC_OVERRIDE (to ignore permission checks) that works like cp. But in order to make sure it doesn't allow the backup user to overwrite arbitrary files, it could remove CAP_DAC_OVERRIDE from the effective set before opening each output file.

As to your bonus question: Nothing prevents them being set back to effective, if arbitrary code can be run. But it can be useful in the event of other compromise (e.g., you convince the program to attempt to overwrite an arbitrary file via symlink attack).

  • I liked the clarity of your imho good example. Relating to that I still think that the use case is made totally clear as if some part of the program should drop the capability this code could be after a fork and drop, hence making the effective and permitted set only necessary from a performance programming style perspective, am I mistaking? For getting to know capabilities in linux I agree with blog.ploetzli.ch/2014/understanding-linux-capabilities that the terminology is confusing, thank you for answering the question therefore! – humanityANDpeace Jul 28 '16 at 17:00
  • @humanityANDpeace In this case, yeah, it could fork and remove the capability from the permitted set, then take the content over a pipe. – derobert Jul 28 '16 at 17:05
3

The difference between effective/permitted capabilities is similar to the difference between real/effective UIDs in setuid programs. The idea isn't to stop a rogue app from escalating privs (you wouldn't grant them privs in the first place, same as you wouldn't setuid them) but to allow a program to run with minimal privileges and only escalate where necessary. This helps minimize the impact of bugs

A very contrived example: I want to have a program that will let me send a SIGHUP to processes owned by the user or to allow a God user to send SIGHUP to init.

This program has the CAP_KILL capability set on the file.

The pseudo code might look something like:

drop_effective CAP_KILL
repeat forever:
  get_process_id_from user
  if process_id==1 and user_is_God:
    set_effective CAP_KILL
    kill(-1,1)
    drop_effective CAP_KILL
 else:
   kill(-1,process_id)

The obvious bug, here, is that I don't check that the user is allowed to send the signal in the first place. Because I've dropped the effective CAP_KILL permission I won't be allowing the user to kill processes other than their own.

Very contrived, for sure! But the idea is to run as far as possible with "least privileges" and only enable privileges when necessary.

Now this won't necessarily protect against buffer overflow attacks because the injected code could enable permitted privileges, so capability aware code should also drop permitted privileges once they are no longer needed; eg a webserver might drop CAP_NET_BIND_SERVICE after it has bound to port 80. You can't enable something not in your permitted set!

  • So the benefit of the additional effective mask of capabilities is to drop temporarily, attempting to harden against certain types of less harmful bugs (i.e. no arbitrary code execution in the processes context), did I understand that more or less correctly? – humanityANDpeace Jul 28 '16 at 16:54
  • Pretty much, yeah. It's a standard design in secure programming; only activate the permissions you need when you need them. It can help mitigate against a class of bugs. – Stephen Harris Jul 28 '16 at 16:56

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.