On Friday 25 January 2013 19:10:53 Gilles Dartiguelongue wrote: > It's not like libcap is a big dependency true, but not everyone needs this, nor can everyone leverage it (caps). it's a linux-centric implementation and is dependent upon filesystem support being available & enabled. that doesn't entirely justify making it a USE flag (since the code already has runtime fallback logic for when the fs doesn't support things), but since the USE is low overhead and leverages logic that already has to be there, i have no problem keeping it. plus it defaults to on. > and it's not like this is an > attempt to make the system more secure by according just the privileges > needed for apps to work as intended, right ? mmm that's exactly what this is > If the USE flag must stay, how is it different that current caps USE > flag ? It applies and not just enables support but is that relevant to > the purpose at hand ? USE=caps is for apps to control their runtime privs (there's also packages which want to query things like coreutils, but let's ignore those). in order to grant themselves reduced privs, they have to start with them in the first place -- capabilities allows you to remove privs from yourself, not extend them. that's accomplished (classically & today) by having the program set*id. thus, when the program is run, it is (typically) launched as the root user which means they have the full capset. if the package supports USE=caps, then it means the program is intelligent enough to know what capabilities it needs and so it can drop all of the rest before executing the main body of code. if it doesn't support USE=caps, then it either tries to do all the superuser stuff first and then drop its uid back down to the executing user's. if it can't do that, then it has to be super careful about everything it does. some packages (like openssh and Google Chrome -- not great examples, but good enough) implement even more complicated setups with privilege separation where there is IPC between a privileged process and an unprivileged one. either way, obviously the more code you have, the harder it is to make sure you get it right (and history is littered with vulns where people didn't). so wouldn't it be nice if you could set the required capabilities on a binary and drop the set*id entirely ? that's what USE=filecaps gets us. now there is no time frame within which you can attack and gain elevated privileges -- the kernel will have the new program start off with the right capset from the very beginning. obviously i'm glossing over bugs where people can get get a program to do things it shouldn't with the capset it didn't drop, but that scenario exists regardless of set*id and USE=caps behavior. in the ideal world: - USE=filecaps so you start only with the caps you need - not be set*id at all - do all the things at the very beginning that require the elevated caps - support USE=caps so you can then drop all of your elevated caps - run like normal and process all user input as an example, let's look at ping. we give it set*id because people want to be able to do something innocuous as `ping 192.168.0.1` w/out `sudo` first. in order to send ICMP_ECHO packets, it needs to create a SOCK_RAW socket which the kernel doesn't allow random users to create (otherwise they could generate arbitrary packets on the network). when USE=-cap, the first thing ping does is create the socket, then drop the root uid. when USE=cap, the first thing it does is drop all of its permitted caps to the bare min what it needs in the future, and then sets the effective even lower. when it needs to open the socket, it sets the effective to what it needs, opens the socket, and then sets the effective lower again. rinse/repeat. at least, this is all my understanding of things. i could be completely wrong, so feel free to correct something if you notice it. -mike