On Sun, Dec 2, 2012 at 6:20 PM, Andrew G. Morgan <mor...@kernel.org> wrote: > On Sun, Dec 2, 2012 at 3:04 PM, Andy Lutomirski <l...@amacapital.net> wrote: >> On Sun, Dec 2, 2012 at 2:26 PM, Andrew G. Morgan <mor...@kernel.org> wrote: >>> On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <l...@amacapital.net> >>> wrote: >>>> On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <mor...@kernel.org> wrote: >>>>> There is a fairly well written paper ;-) explaining how things are >>>>> supposed to work: >>>>> >>>>> http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf >>>>> >>>>> The inheritable set is not intended to work the way you seem to want. >>>>> Naive inheritance like that is quite explicitly the opposite of what >>>>> was designed. >>>> >>>> I'm aware that the system was designed, or perhaps evolved, to prevent >>>> users with uid != 0 from inheriting capabilities unless vfs >>>> inheritable caps are granted on a per-file basis. I want a way around >>>> that -- I want to mix non-root, capabilities, and exec. This is damn >>>> near impossible right now if I don't have CAP_SETFCAP or root's >>>> explicit, per-program cooperation. CAP_SETFCAP is essentially >>>> equivalent to "let me do anything". >>>> >>>> As it stands, using something like pam_cap to grant a user cap_net_raw >>>> is useless -- that user can't use the privilege because (unless uid == >>>> 0) the privilege will never end up in the permitted set. >>> >>> Have you tried adding fI of cap_net_raw to the file to be executed? >> >> Yes, and it works. I don't like this solution because: >> >> a) It doesn't scale in terms of sysadmin resources required. > > By doesn't scale, you mean it requires the admin to define which > actual binaries on their system can wield privilege?
Yes. >> >> c) tcpdump isn't really special. I trust this user account with >> cap_net_raw, and that should be all the configuration I need. > > But this is a statement about access control, and not a statement > about privilege. You trust the user to invoke something that can do > tcpdump, you don't really trust the user to generate arbitrary packets > on the network. That *really* doesn't scale. Suppose I trust one user to capture packets and a second user to run portscans. Setting tcpdump and nmap as cap_net_raw+i and granting both users cap_net_raw (inheritable) doesn't do it. (Even ignoring the possibility of bugs in tcpdump and nmap.) In the immediate case that prompted this question, I only really trust the user to run tcpdump, although I don't particularly care if they generate arbitrary packets. For simplicity, if I could use full capability inheritance, I'd probably just grant cap_net_raw and be done with it. In this case, though, I have a helper that's ~50 lines of code that has cap_net_raw=p. It checks that it's happy about what's going on, it does some apparmor twiddling (sigh), and it execve's /usr/sbin/tcpdump. And it only works because I set tcpdump as cap_net_raw+i. The ability to run helper programs is *useful*. I find it rather limiting that privileged programs that don't have uid=0 can't really do it without administrative help. > >> d) If I really wanted, I could emulate execve without actually doing >> execve, and capabilities would be inherited. > > If you could modify the executable properties of the binary that has > the privilege to wield a privilege then you are either exploiting an > app bug, or doing something the privileged binary has been trusted to > do. That's not what I mean. I would: fork() munmap everything mmap ld.so set up a fake initial stack and the right fd or mapping or whatever just to ld-linux.so That's almost execve, and privilege inheritance works. > >> The issue with allowing real capability inheritance is that, >> currently, it's safe for a program with fP != 0 to add an inheritable >> capability and then execve something caller-controlled. I don't know >> whether anything actually does this, but it's hard to prove that >> nothing does. Hence my idea of requiring no_new_privs to make >> capabilities inheritable. > > Assuming this is not another app bug, and that's what the executable > with fP != 0 does, then that's why it was given fP != 0 - its what the > program was designed to do. Why is this an issue? > >> An alternative, and considerably more intrusive, change would be to >> add a fourth mask of genuinely inheritable capabilities. > > If you believe that you want to give a user the privilege to grant a > privilege to an arbitrary binary to do things like this, why not write > an app that adds file capabilities to target binaries owned by the > user? You can make it execute-only by said user and let them do > whatever they want. This requires no kernel changes. Egads. IMO that's way scarier. I'd rather just mark ld.so as <everything>=i. My point about no_new_privs is: if I trust a user or a program with a capability, I probably also trust it to invoke helpers (via execve) as it sees fit. What I don't trust is everything else on the system that has fP or set[ug]id bits set -- they probably weren't written to anticipate inheritable capabilities and something like the sendmail bug might happen again. With no_new_privs set, though, that whole vulnerability surface is gone -- the fP bits, setuid, and setgid are inoperable. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/