Skip to contentSkip to conversation

posix capabilities inheritance

DISCUSSION Michael Glasgow 5 participants 6 messages Oct 23, 2003 – Oct 25, 2003 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw
Quoted 11 lines · Theodore Ts'o

I agree this is safe, and allows the use of your setuid wrapper script. The one reason why I think it's better to modify programs is that it's too easy for individual system administrators to screw up the configuration used by your wrapper script, and accidentally introduce a security vulnerability into their system. It's dangerous to give a program some capability (or reduce the capability given to a program designed to be setuid) without examining the source code and being clueful. So by making the program setuid and editing the source code to add an explicit capability drop in the program is much, much safer compared to having a random system administrator to edit a config file and trust that he or she does so correctly.

I can see your point, but I guess we'll have to agree to disagree.

Even with selective capability inheritance enabled in this fashion, it is still possible to avoid using it and modify programs directly, if you think that's more secure. Personally, I think that in some cases it's slightly more secure to have a very small (statically linked) setuid wrapper program which sets up capabilities properly than to make a very large program setuid-root (when it was not designed to run as root), only to add one capability.

Yes, you can do the capability-setup first thing in main()... but this is occasionally insufficient. Also, it makes it a pain to have, for instance, a backup user with CAP_DAC_READ_SEARCH who is able to run several apps, e.g. dump, tar, cpio, rsync, etc. from a restricted shell.

The code to drop privs is not hard, but it's also not trivial. Those without a clue are just as likely to screw it up as they are a wrapper; and anyway since when did it become a design goal for the kernel to cater to the ineptitude of the clueless? That sounds more like a Redmond, Washington philosophy than one fit for Linux. :-)

--
Michael Glasgow < glasgow at beer dot net >

#2 lore raw
Quoted 14 lines · Michael Glasgow

Even with selective capability inheritance enabled in this fashion, it is still possible to avoid using it and modify programs directly, if you think that's more secure. Personally, I think that in some cases it's slightly more secure to have a very small (statically linked) setuid wrapper program which sets up capabilities properly than to make a very large program setuid-root (when it was not designed to run as root), only to add one capability.

Yes, you can do the capability-setup first thing in main()... but this is occasionally insufficient. Also, it makes it a pain to have, for instance, a backup user with CAP_DAC_READ_SEARCH who is able to run several apps, e.g. dump, tar, cpio, rsync, etc. from a restricted shell.

Quoted 5 lines

The code to drop privs is not hard, but it's also not trivial. Those without a clue are just as likely to screw it up as they are a wrapper; and anyway since when did it become a design goal for the kernel to cater to the ineptitude of the clueless? That sounds more like a Redmond, Washington philosophy than one fit for Linux. :-)

Modifying source code requires programming capabilities, which means that the most clueless won't do it at all. It's something that needs to be done by the upstream authors, or perhaps by the distributions, at which point the clueless will get it when they upgrade.

It's not matter of catering to the ineptitude of the clueless but pursueing a design which doesn't leave an open manhole cover where a clueless system administrator can screw up and put their entire system at risk. Consider that even if the distributions ship a package using your system, there will be a config file which will be an opportunity for a system administrator to screw up. In general, for any particular system program, there is only one acceptable setting in terms of what capabilities it will need. So why make it be something which can be screwed up in a config file?

Fix it once, by a programmer who knows what he/she is doing, and the problem is fixed for everyone. Furthermore, it will be more efficient since it avoids an exec and requirement for a program to parse a config file.

- Ted

#3 lore raw
In reply to Michael Glasgow
Quoted 1 line · Michael Glasgow

The code to drop privs is not hard, but it's also not trivial.

Here's an example code sequence that demonstrates how a setuid-to-root application could drop all capabilities except for CAP_IPC_LOCK and then run with the non-privileged uid:

    #include <sys/prctl.h>
    #include <sys/capability.h>

	...

	cap_t c;

	if (prctl(PR_SET_KEEPCAPS, 1UL, 0UL, 0UL, 0UL) < 0 ||
	    seteuid(getuid()) < 0 ||
	    !(c = cap_from_text("cap_ipc_lock=eip")) ||
	    cap_set_proc(c) < 0)
		/* handle error */;

However, I agree that it's often not viable to require application changes to achieve the desired result.

Cheers. -ernie

#4 lore raw
Quoted 2 lines · In article <[email protected]> you wrote:

However, I agree that it's often not viable to require application changes to achieve the desired result.

What does often mean? This is the Open Source Linux, and here we can do changes to the source if it is good for securtiy, architecture, speat, whatever.

Of course a solution which does the right thing without programming is even better - Watermarking or something. But I guess wie can combine those. The typical internet server has already enough cruft for chrooting, priveledge dropping and FD passing to work around for example port priveledges, a REAL solution wont make it worse.

Bernd
y

#5 lore raw
Quoted 7 lines · Bernd Eckenfels
Quoted 2 lines · In article <[email protected]> you wrote:

However, I agree that it's often not viable to require application changes to achieve the desired result.

What does often mean? This is the Open Source Linux, and here we can do changes to the source if it is good for securtiy, architecture, speat, whatever.

I agree, but sometimes the source to the *application* is not available to us.

Cheers. -ernie

#6 lore raw
In reply to Ernie Petrides

Hi!

Quoted 19 lines
Quoted 1 line

The code to drop privs is not hard, but it's also not trivial.

Here's an example code sequence that demonstrates how a setuid-to-root application could drop all capabilities except for CAP_IPC_LOCK and then run with the non-privileged uid:

    #include <sys/prctl.h>
    #include <sys/capability.h>

	...

	cap_t c;

	if (prctl(PR_SET_KEEPCAPS, 1UL, 0UL, 0UL, 0UL) < 0 ||
	    seteuid(getuid()) < 0 ||
	    !(c = cap_from_text("cap_ipc_lock=eip")) ||
	    cap_set_proc(c) < 0)
		/* handle error */;
Quoted 2 lines

However, I agree that it's often not viable to require application changes to achieve the desired result.

IIRC, libraries have special startup sections that run before main(). And c++ constructors do, too; so wrapper still might be safer option.

Pavel

Signature · 2 lines
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]