* [RFC] Capabilities still can't be inherited by normal programs @ 2012-12-02 3:04 Andy Lutomirski 2012-12-02 17:21 ` Andrew G. Morgan 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-02 3:04 UTC (permalink / raw) To: linux-kernel, linux-security-module Cc: Kees Cook, James Morris, Eric Paris, Andrew G. Morgan I'd like to be able to run programs (like bash!) as nonroot but with some capabilities granted. After all these years, it's almost, but not quite, possible. This is because the transition rule (if root isn't involved or NOROOT is set) is pP' = (pB' & fP) | (pI' & fI), and, when execing a program without vfs caps set, fI = 0. I want to set PR_SET_KEEPCAPS, setuid away from root, set some capability as inheritable, and exec something. That capability stays inheritable, but it doesn't end up permitted. Oops. (There's another alarming thing that happens -- programs end up with capability bits that are inheritable but not permitted. I'd like to change cap_bprm_set_creds to clear all inheritable bits that don't end up in the final permitted set to minimize confusion. Of course, this *could* (but seems unlikely to) trigger security bugs.) The obvious but scary fix is to make everything act like fI = <all caps> if vfs caps aren't set. It's not immediately obvious why this would be bad: no task has any inheritable capabilities by default. Something like the sendmail bug is unlikely here -- this change would give *more* caps, not fewer, and it could be done in such a way that setuid binaries don't inherit caps. A less scary way would be to make it opt-in: set a securebit if you want default capability inheritance. This requires CAP_SETPCAP, which seems to be shorthand for "allow me to shoot myself in the foot". Sensible programs might set no_new_privs when they set this securebit. An even less scary way would be to require a new securebit *and* no_new_privs. Any suggestions? I'm happy to write patches, but I'd rather not cook up ten patches and have this get stuck in limbo for years. For some rationale: I want to write a program that has cap_net_raw permitted as a file capability. That program will do some checks and then invoke tcpdump. I can't do this: tcpdump can't inherit capabilities into its permitted set unless I set the cap_net_raw inheritable bit on it. --Andy P.S. The get_file_caps code is gross. Whatever the outcome of this discussion, I'll submit a patch to clean it up, and I'll probably add a file to Documentation/security for good measure. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-02 3:04 [RFC] Capabilities still can't be inherited by normal programs Andy Lutomirski @ 2012-12-02 17:21 ` Andrew G. Morgan 2012-12-02 18:35 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Andrew G. Morgan @ 2012-12-02 17:21 UTC (permalink / raw) To: Andy Lutomirski Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn 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. Cheers Andrew On Sat, Dec 1, 2012 at 7:04 PM, Andy Lutomirski <luto@amacapital.net> wrote: > I'd like to be able to run programs (like bash!) as nonroot but with > some capabilities granted. After all these years, it's almost, but > not quite, possible. This is because the transition rule (if root > isn't involved or NOROOT is set) is pP' = (pB' & fP) | (pI' & fI), > and, when execing a program without vfs caps set, fI = 0. I want to > set PR_SET_KEEPCAPS, setuid away from root, set some capability as > inheritable, and exec something. That capability stays inheritable, > but it doesn't end up permitted. Oops. > > (There's another alarming thing that happens -- programs end up with > capability bits that are inheritable but not permitted. I'd like to > change cap_bprm_set_creds to clear all inheritable bits that don't end > up in the final permitted set to minimize confusion. Of course, this > *could* (but seems unlikely to) trigger security bugs.) > > The obvious but scary fix is to make everything act like fI = <all > caps> if vfs caps aren't set. It's not immediately obvious why this > would be bad: no task has any inheritable capabilities by default. > Something like the sendmail bug is unlikely here -- this change would > give *more* caps, not fewer, and it could be done in such a way that > setuid binaries don't inherit caps. > > A less scary way would be to make it opt-in: set a securebit if you > want default capability inheritance. This requires CAP_SETPCAP, which > seems to be shorthand for "allow me to shoot myself in the foot". > Sensible programs might set no_new_privs when they set this securebit. > > An even less scary way would be to require a new securebit *and* no_new_privs. > > Any suggestions? I'm happy to write patches, but I'd rather not cook > up ten patches and have this get stuck in limbo for years. > > For some rationale: I want to write a program that has cap_net_raw > permitted as a file capability. That program will do some checks and > then invoke tcpdump. I can't do this: tcpdump can't inherit > capabilities into its permitted set unless I set the cap_net_raw > inheritable bit on it. > > --Andy > > P.S. The get_file_caps code is gross. Whatever the outcome of this > discussion, I'll submit a patch to clean it up, and I'll probably add > a file to Documentation/security for good measure. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-02 17:21 ` Andrew G. Morgan @ 2012-12-02 18:35 ` Andy Lutomirski 2012-12-02 22:26 ` Andrew G. Morgan 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-02 18:35 UTC (permalink / raw) To: Andrew G. Morgan Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@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. I want to come up with a way to change this that will, convincingly, not open up any new security holes. The current concept of process inheritable capabilities seems so vague and so oddly defined that I'm not sure I want to touch it. In an ideal world, I'd want pI <= pP and fP <= fI to be invariants, and I'd like programs without vfs caps set to have fI = <everything>. Making this change will surely break something, though. I'm looking for ideas. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-02 18:35 ` Andy Lutomirski @ 2012-12-02 22:26 ` Andrew G. Morgan 2012-12-02 23:04 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Andrew G. Morgan @ 2012-12-02 22:26 UTC (permalink / raw) To: Andy Lutomirski Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <luto@amacapital.net> wrote: > On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@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? Cheers Andrew > > I want to come up with a way to change this that will, convincingly, > not open up any new security holes. The current concept of process > inheritable capabilities seems so vague and so oddly defined that I'm > not sure I want to touch it. In an ideal world, I'd want pI <= pP and > fP <= fI to be invariants, and I'd like programs without vfs caps set > to have fI = <everything>. Making this change will surely break > something, though. > > I'm looking for ideas. > > --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-02 22:26 ` Andrew G. Morgan @ 2012-12-02 23:04 ` Andy Lutomirski 2012-12-03 2:20 ` Andrew G. Morgan 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-02 23:04 UTC (permalink / raw) To: Andrew G. Morgan Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Sun, Dec 2, 2012 at 2:26 PM, Andrew G. Morgan <morgan@kernel.org> wrote: > On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <luto@amacapital.net> wrote: >> On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@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. b) It adds no real security over real inheritable capabilities. I'd be rather surprised if tcpdump does not have any bugs that would allow me to subvert it to recover its inherited capabilities. For example, it drops privileges like this: if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) fprintf(stderr, "Warning: setgid/setuid failed !\n"); This is buggy for at least two reasons: it doesn't abort on error and setuid doesn't actually drop capabilities when uid 0 isn't involved. c) tcpdump isn't really special. I trust this user account with cap_net_raw, and that should be all the configuration I need. d) If I really wanted, I could emulate execve without actually doing execve, and capabilities would be inherited. 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. An alternative, and considerably more intrusive, change would be to add a fourth mask of genuinely inheritable capabilities. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-02 23:04 ` Andy Lutomirski @ 2012-12-03 2:20 ` Andrew G. Morgan 2012-12-03 4:48 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Andrew G. Morgan @ 2012-12-03 2:20 UTC (permalink / raw) To: Andy Lutomirski Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Sun, Dec 2, 2012 at 3:04 PM, Andy Lutomirski <luto@amacapital.net> wrote: > On Sun, Dec 2, 2012 at 2:26 PM, Andrew G. Morgan <morgan@kernel.org> wrote: >> On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <luto@amacapital.net> wrote: >>> On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@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? > b) It adds no real security over real inheritable capabilities. I'd > be rather surprised if tcpdump does not have any bugs that would allow > me to subvert it to recover its inherited capabilities. For example, > it drops privileges like this: In other words, an app bug can leak a privilege - one of the privileges that it is explicitly trusted to wield. Its hard to see how this isn't an app bug. > if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) > fprintf(stderr, "Warning: setgid/setuid failed !\n"); > > This is buggy for at least two reasons: it doesn't abort on error and > setuid doesn't actually drop capabilities when uid 0 isn't involved. Right. > > 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. > 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. > 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. Cheers Andrew ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-03 2:20 ` Andrew G. Morgan @ 2012-12-03 4:48 ` Andy Lutomirski 2012-12-04 13:54 ` Serge E. Hallyn 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-03 4:48 UTC (permalink / raw) To: Andrew G. Morgan Cc: linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Sun, Dec 2, 2012 at 6:20 PM, Andrew G. Morgan <morgan@kernel.org> wrote: > On Sun, Dec 2, 2012 at 3:04 PM, Andy Lutomirski <luto@amacapital.net> wrote: >> On Sun, Dec 2, 2012 at 2:26 PM, Andrew G. Morgan <morgan@kernel.org> wrote: >>> On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <luto@amacapital.net> wrote: >>>> On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-03 4:48 ` Andy Lutomirski @ 2012-12-04 13:54 ` Serge E. Hallyn 2012-12-05 19:32 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Serge E. Hallyn @ 2012-12-04 13:54 UTC (permalink / raw) To: Andy Lutomirski Cc: Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn Quoting Andy Lutomirski (luto@amacapital.net): > >> 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. But of course that is why you only want to fill fI on programs you trust not to do that. What you are arguing is that you want to give fI on programs you don't trust anyway, and so heck why not just give it on everything. Anyway, implementing the features you want in a new module is encouraged, so long as the behavior of existing module stays the same. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-04 13:54 ` Serge E. Hallyn @ 2012-12-05 19:32 ` Andy Lutomirski 2012-12-05 20:12 ` Markku Savela 2012-12-05 21:05 ` Serge Hallyn 0 siblings, 2 replies; 36+ messages in thread From: Andy Lutomirski @ 2012-12-05 19:32 UTC (permalink / raw) To: Serge E. Hallyn Cc: Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: > Quoting Andy Lutomirski (luto@amacapital.net): >> >> 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. > > But of course that is why you only want to fill fI on programs you trust > not to do that. What you are arguing is that you want to give fI on > programs you don't trust anyway, and so heck why not just give it on > everything. > Huh? I'd set fP on a program I expect to do *exactly* that (or use actual in-kernel capability inheritance, which I would find vastly more pleasant). If I give a program a capability (via fP or fI & pI), then I had better trust it not to abuse that capability. Having it pass that capability on to a child helper process would be just fine with me *because it already has that capability*. The problem with the current inheritance mechanism is that it's very difficult to understand what it means for an fI bit or a pI bit to be set. Saying "set a pI bit using pam if you want to grant permission to that user to run a particular program with fI set" is crap -- it only works if there is exactly one binary on the system with that bit set. In any case, a different administrator or package might use it for something different. Suppose I use the (apparently) current suggested approach: I install a fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that has fP=cap_new_raw and invokes that copy of tcpdump after appropriate validation of parameters. All is well. Now I want to grant only a subset of users permission to run ping. So I modify ping so it's cap_net_raw=i (not p) and grant those users pI=cap_net_raw. The end result: I introduced a security hole: the users with cap_net_raw=i can run tcpdump *without validation via the helper*. Oops. The fundamental problem as I see it is that fI and pI's behavior is so odd that the significance of setting some of those bits varies and is likely to be used, if at all, in conflicting ways. > Anyway, implementing the features you want in a new module is encouraged, > so long as the behavior of existing module stays the same. I'll think about it some more and do it possibly using a sysctl. Adding this kind of stuff in a module is asking for even worse incomprehensibility of which capability bit means what. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-05 19:32 ` Andy Lutomirski @ 2012-12-05 20:12 ` Markku Savela 2012-12-05 21:05 ` Serge Hallyn 1 sibling, 0 replies; 36+ messages in thread From: Markku Savela @ 2012-12-05 20:12 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On 12/05/2012 09:32 PM, Andy Lutomirski wrote: >> >Anyway, implementing the features you want in a new module is encouraged, >> >so long as the behavior of existing module stays the same. > I'll think about it some more and do it possibly using a sysctl. > Adding this kind of stuff in a module is asking for even worse > incomprehensibility of which capability bit means what. For what is worth, and just for information. This module approach has been attempted, sort of: I did implement capabilities inheritance in Nokia N9 (Aegis). The capabilities started to inherit when task entered "aegis mode" (a bit in secure bits). The experience was "interesting". There are many "simplified" articles about running root with less than full capabilities, and we did that. However, it also caused a lot of headache, because many people got hit by this "root is no more omnipotent" thing and complained. It was a pain to manage and find correct required for each task and often end result was to grant all (or at least too much). ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-05 19:32 ` Andy Lutomirski 2012-12-05 20:12 ` Markku Savela @ 2012-12-05 21:05 ` Serge Hallyn 2012-12-05 21:46 ` Andy Lutomirski 1 sibling, 1 reply; 36+ messages in thread From: Serge Hallyn @ 2012-12-05 21:05 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn Quoting Andy Lutomirski (luto@amacapital.net): > On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: > > Quoting Andy Lutomirski (luto@amacapital.net): > >> >> 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. > > > > But of course that is why you only want to fill fI on programs you trust > > not to do that. What you are arguing is that you want to give fI on > > programs you don't trust anyway, and so heck why not just give it on > > everything. > > > > Huh? I'd set fP on a program I expect to do *exactly* that (or use > actual in-kernel capability inheritance, which I would find vastly > more pleasant). If I give a program a capability (via fP or fI & pI), > then I had better trust it not to abuse that capability. Having it > pass that capability on to a child helper process would be just fine > with me *because it already has that capability*. > > The problem with the current inheritance mechanism is that it's very > difficult to understand what it means for an fI bit or a pI bit to be > set. Saying "set a pI bit using pam if you want to grant permission > to that user to run a particular program with fI set" is crap -- it > only works if there is exactly one binary on the system with that bit > set. In any case, a different administrator or package might use it > for something different. > > Suppose I use the (apparently) current suggested approach: I install a > fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that > has fP=cap_new_raw and invokes that copy of tcpdump after appropriate > validation of parameters. All is well. Since you're writing a special helper, you can surely have it validate the userid and make it so the calling user doesn't have to have cap_net_raw in pI? > Now I want to grant only a subset of users permission to run ping. So > I modify ping so it's cap_net_raw=i (not p) and grant those users > pI=cap_net_raw. > > The end result: I introduced a security hole: the users with > cap_net_raw=i can run tcpdump *without validation via the helper*. > Oops. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-05 21:05 ` Serge Hallyn @ 2012-12-05 21:46 ` Andy Lutomirski 2012-12-05 22:20 ` Serge Hallyn 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-05 21:46 UTC (permalink / raw) To: Serge Hallyn Cc: Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: > Quoting Andy Lutomirski (luto@amacapital.net): >> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: >> > Quoting Andy Lutomirski (luto@amacapital.net): >> >> >> 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. >> > >> > But of course that is why you only want to fill fI on programs you trust >> > not to do that. What you are arguing is that you want to give fI on >> > programs you don't trust anyway, and so heck why not just give it on >> > everything. >> > >> >> Huh? I'd set fP on a program I expect to do *exactly* that (or use >> actual in-kernel capability inheritance, which I would find vastly >> more pleasant). If I give a program a capability (via fP or fI & pI), >> then I had better trust it not to abuse that capability. Having it >> pass that capability on to a child helper process would be just fine >> with me *because it already has that capability*. >> >> The problem with the current inheritance mechanism is that it's very >> difficult to understand what it means for an fI bit or a pI bit to be >> set. Saying "set a pI bit using pam if you want to grant permission >> to that user to run a particular program with fI set" is crap -- it >> only works if there is exactly one binary on the system with that bit >> set. In any case, a different administrator or package might use it >> for something different. >> >> Suppose I use the (apparently) current suggested approach: I install a >> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that >> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate >> validation of parameters. All is well. > > Since you're writing a special helper, you can surely have it validate > the userid and make it so the calling user doesn't have to have > cap_net_raw in pI? I can and did. The mere presence of a cap_net_raw+i tcpdump binary is more or less equivalent to saying that users with cap_net_raw in pI can capture packets. I've just prevented pI=cap_net_raw from meaning anything less than "can capture packets". So I think we should bite the bullet and just let programs opt in (via some appropriately careful mechanism) to real capability inheritance. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-05 21:46 ` Andy Lutomirski @ 2012-12-05 22:20 ` Serge Hallyn 2012-12-07 0:57 ` Casey Schaufler 0 siblings, 1 reply; 36+ messages in thread From: Serge Hallyn @ 2012-12-05 22:20 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Andy Lutomirski (luto@amacapital.net): > On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: > > Quoting Andy Lutomirski (luto@amacapital.net): > >> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: > >> > Quoting Andy Lutomirski (luto@amacapital.net): > >> >> >> 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. > >> > > >> > But of course that is why you only want to fill fI on programs you trust > >> > not to do that. What you are arguing is that you want to give fI on > >> > programs you don't trust anyway, and so heck why not just give it on > >> > everything. > >> > > >> > >> Huh? I'd set fP on a program I expect to do *exactly* that (or use > >> actual in-kernel capability inheritance, which I would find vastly > >> more pleasant). If I give a program a capability (via fP or fI & pI), > >> then I had better trust it not to abuse that capability. Having it > >> pass that capability on to a child helper process would be just fine > >> with me *because it already has that capability*. > >> > >> The problem with the current inheritance mechanism is that it's very > >> difficult to understand what it means for an fI bit or a pI bit to be > >> set. Saying "set a pI bit using pam if you want to grant permission > >> to that user to run a particular program with fI set" is crap -- it > >> only works if there is exactly one binary on the system with that bit > >> set. In any case, a different administrator or package might use it > >> for something different. > >> > >> Suppose I use the (apparently) current suggested approach: I install a > >> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that > >> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate > >> validation of parameters. All is well. > > > > Since you're writing a special helper, you can surely have it validate > > the userid and make it so the calling user doesn't have to have > > cap_net_raw in pI? > > I can and did. Oh, oops, I mis-understood what you meant was the problem. Yup, that is a real limitation. Yes, with the posix file caps you will be disappointed unless you see pI=X as "this user may run any program which is Inh-trusted with X" and fI=X as "this program may be run with X by any user Inh-trusted with X". It almost makes me want to say that there should be an execve-analogue to prctl(PR_SET_KEEPCAPS), which says caps will remain unchanged for one execve. Or perhaps an intermediate securebits state between !SECBIT_NOROOT and SECBIT_NOROOT, which automatically transitions after the first execve to SECBIT_NOROOT. > The mere presence of a cap_net_raw+i tcpdump binary is more or less > equivalent to saying that users with cap_net_raw in pI can capture > packets. I've just prevented pI=cap_net_raw from meaning anything > less than "can capture packets". So I think we should bite the bullet > and just let programs opt in (via some appropriately careful > mechanism) to real capability inheritance. By real you mean more precise. I think it'd be very interesting to get together with Markku and learn more from the N9 experiment! Markku, are there any post-mortem analysis papers we can read for starters? Andy would not be trying to restrict root in general, so the ramification you cited may not necessarily be relevant. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-05 22:20 ` Serge Hallyn @ 2012-12-07 0:57 ` Casey Schaufler 2012-12-07 14:42 ` Serge E. Hallyn 0 siblings, 1 reply; 36+ messages in thread From: Casey Schaufler @ 2012-12-07 0:57 UTC (permalink / raw) To: Serge Hallyn Cc: Andy Lutomirski, Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela, Casey Schaufler On 12/5/2012 2:20 PM, Serge Hallyn wrote: > Quoting Andy Lutomirski (luto@amacapital.net): >> On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: >>> Quoting Andy Lutomirski (luto@amacapital.net): >>>> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: >>>>> Quoting Andy Lutomirski (luto@amacapital.net): >>>>>>>> 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. >>>>> But of course that is why you only want to fill fI on programs you trust >>>>> not to do that. What you are arguing is that you want to give fI on >>>>> programs you don't trust anyway, and so heck why not just give it on >>>>> everything. >>>>> >>>> Huh? I'd set fP on a program I expect to do *exactly* that (or use >>>> actual in-kernel capability inheritance, which I would find vastly >>>> more pleasant). If I give a program a capability (via fP or fI & pI), >>>> then I had better trust it not to abuse that capability. Having it >>>> pass that capability on to a child helper process would be just fine >>>> with me *because it already has that capability*. >>>> >>>> The problem with the current inheritance mechanism is that it's very >>>> difficult to understand what it means for an fI bit or a pI bit to be >>>> set. Saying "set a pI bit using pam if you want to grant permission >>>> to that user to run a particular program with fI set" is crap -- it >>>> only works if there is exactly one binary on the system with that bit >>>> set. In any case, a different administrator or package might use it >>>> for something different. >>>> >>>> Suppose I use the (apparently) current suggested approach: I install a >>>> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that >>>> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate >>>> validation of parameters. All is well. >>> Since you're writing a special helper, you can surely have it validate >>> the userid and make it so the calling user doesn't have to have >>> cap_net_raw in pI? >> I can and did. > Oh, oops, I mis-understood what you meant was the problem. > > Yup, that is a real limitation. > > Yes, with the posix file caps you will be disappointed unless you see > pI=X as "this user may run any program which is Inh-trusted with X" and > fI=X as "this program may be run with X by any user Inh-trusted with X". > > It almost makes me want to say that there should be an execve-analogue > to prctl(PR_SET_KEEPCAPS), which says caps will remain unchanged for one > execve. Or perhaps an intermediate securebits state between > !SECBIT_NOROOT and SECBIT_NOROOT, which automatically transitions after > the first execve to SECBIT_NOROOT. > >> The mere presence of a cap_net_raw+i tcpdump binary is more or less >> equivalent to saying that users with cap_net_raw in pI can capture >> packets. I've just prevented pI=cap_net_raw from meaning anything >> less than "can capture packets". So I think we should bite the bullet >> and just let programs opt in (via some appropriately careful >> mechanism) to real capability inheritance. > By real you mean more precise. I think it'd be very interesting to get > together with Markku and learn more from the N9 experiment! > > Markku, are there any post-mortem analysis papers we can read for > starters? Andy would not be trying to restrict root in general, so > the ramification you cited may not necessarily be relevant. > > -serge http://wt.tuxomania.net/publications/posix.1e/download.html Everyone should read the capabilities rationale. It answers most of the questions on this thread, and a bunch more. The capabilities mechanism has to support what are currently setuid-root programs without change and allow for new programs that use the mechanism wisely and fully. > -- > To unsubscribe from this list: send the line "unsubscribe linux-security-module" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-07 0:57 ` Casey Schaufler @ 2012-12-07 14:42 ` Serge E. Hallyn 2012-12-07 17:00 ` Casey Schaufler ` (2 more replies) 0 siblings, 3 replies; 36+ messages in thread From: Serge E. Hallyn @ 2012-12-07 14:42 UTC (permalink / raw) To: Casey Schaufler Cc: Serge Hallyn, Andy Lutomirski, Serge E. Hallyn, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Casey Schaufler (casey@schaufler-ca.com): > On 12/5/2012 2:20 PM, Serge Hallyn wrote: > > Quoting Andy Lutomirski (luto@amacapital.net): > >> On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: > >>> Quoting Andy Lutomirski (luto@amacapital.net): > >>>> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: > >>>>> Quoting Andy Lutomirski (luto@amacapital.net): > >>>>>>>> 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. > >>>>> But of course that is why you only want to fill fI on programs you trust > >>>>> not to do that. What you are arguing is that you want to give fI on > >>>>> programs you don't trust anyway, and so heck why not just give it on > >>>>> everything. > >>>>> > >>>> Huh? I'd set fP on a program I expect to do *exactly* that (or use > >>>> actual in-kernel capability inheritance, which I would find vastly > >>>> more pleasant). If I give a program a capability (via fP or fI & pI), > >>>> then I had better trust it not to abuse that capability. Having it > >>>> pass that capability on to a child helper process would be just fine > >>>> with me *because it already has that capability*. > >>>> > >>>> The problem with the current inheritance mechanism is that it's very > >>>> difficult to understand what it means for an fI bit or a pI bit to be > >>>> set. Saying "set a pI bit using pam if you want to grant permission > >>>> to that user to run a particular program with fI set" is crap -- it > >>>> only works if there is exactly one binary on the system with that bit > >>>> set. In any case, a different administrator or package might use it > >>>> for something different. > >>>> > >>>> Suppose I use the (apparently) current suggested approach: I install a > >>>> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that > >>>> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate > >>>> validation of parameters. All is well. > >>> Since you're writing a special helper, you can surely have it validate > >>> the userid and make it so the calling user doesn't have to have > >>> cap_net_raw in pI? > >> I can and did. > > Oh, oops, I mis-understood what you meant was the problem. > > > > Yup, that is a real limitation. > > > > Yes, with the posix file caps you will be disappointed unless you see > > pI=X as "this user may run any program which is Inh-trusted with X" and > > fI=X as "this program may be run with X by any user Inh-trusted with X". > > > > It almost makes me want to say that there should be an execve-analogue > > to prctl(PR_SET_KEEPCAPS), which says caps will remain unchanged for one > > execve. Or perhaps an intermediate securebits state between > > !SECBIT_NOROOT and SECBIT_NOROOT, which automatically transitions after > > the first execve to SECBIT_NOROOT. > > > >> The mere presence of a cap_net_raw+i tcpdump binary is more or less > >> equivalent to saying that users with cap_net_raw in pI can capture > >> packets. I've just prevented pI=cap_net_raw from meaning anything > >> less than "can capture packets". So I think we should bite the bullet > >> and just let programs opt in (via some appropriately careful > >> mechanism) to real capability inheritance. > > By real you mean more precise. I think it'd be very interesting to get > > together with Markku and learn more from the N9 experiment! > > > > Markku, are there any post-mortem analysis papers we can read for > > starters? Andy would not be trying to restrict root in general, so > > the ramification you cited may not necessarily be relevant. > > > > -serge > > http://wt.tuxomania.net/publications/posix.1e/download.html > > Everyone should read the capabilities rationale. It answers most > of the questions on this thread, and a bunch more. The capabilities > mechanism has to support what are currently setuid-root programs > without change and allow for new programs that use the mechanism > wisely and fully. How to put this delicately... that is not enjoyable reading :) As I understood it, the draft supports setuid-root programs, but does not support a !SECBIT_NOROOT environment. If that is not the case, can you point to where in the draft that is described? Regardless, 1. Andy describes a problem which AFAICT can't be solved with the current capabilities support. An intermediate state between !SECBIT_NOROOT and SECBIT_NOROOT (which itself is IIUC already an extension beyond the above draft) seems an interesting feature to consider which would support the wrapper case - but not something to run into blindly without considering all the ramifications. 2. The N9 folks have experimented with other inheritence properties, and the details their experience would be educational. There are two other ways the wrappered privileged tcpdump could be achieved: 1. Have the privileged wrapper create a new user and network namespace and pass the network device into the new network namespace and run tcpdump there with privilege. This doesn't work if the specific device also needs to be used in the original network namespace (but passing a device bridged with the one of interest might suffice?). 2. Have the privileged wrapper create a small tmpfs mount in a (non-ms-shared) new mounts namespace, copy tcpdump into that mount and give it fI=CAP_NET_RAW, then execute the child with pI=CAP_NET_RAW. A bit hacky, but prevents the issue of other users with pI=CAP_NET_RAW from executing that tcpdump. Since the child will have pP=CAP_NET_RAW, the other users should be prevented from getting to the modified tcpdump binary through the child's /proc/pid/fd/N. Not saying these are ideal, just trying to think of ways of solving the problem... -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-07 14:42 ` Serge E. Hallyn @ 2012-12-07 17:00 ` Casey Schaufler 2012-12-07 17:07 ` Andrew G. Morgan [not found] ` <CALQRfL6UWLFpTfvan9oirtLdozJqZX4oZwDuQFVnJp8MP06C_Q@mail.gmail.com> 2 siblings, 0 replies; 36+ messages in thread From: Casey Schaufler @ 2012-12-07 17:00 UTC (permalink / raw) To: Serge E. Hallyn Cc: Serge Hallyn, Andy Lutomirski, Andrew G. Morgan, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela, Casey Schaufler On 12/7/2012 6:42 AM, Serge E. Hallyn wrote: > Quoting Casey Schaufler (casey@schaufler-ca.com): >> On 12/5/2012 2:20 PM, Serge Hallyn wrote: >>> Quoting Andy Lutomirski (luto@amacapital.net): >>>> On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: >>>>> Quoting Andy Lutomirski (luto@amacapital.net): >>>>>> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: >>>>>>> Quoting Andy Lutomirski (luto@amacapital.net): >>>>>>>>>> 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. >>>>>>> But of course that is why you only want to fill fI on programs you trust >>>>>>> not to do that. What you are arguing is that you want to give fI on >>>>>>> programs you don't trust anyway, and so heck why not just give it on >>>>>>> everything. >>>>>>> >>>>>> Huh? I'd set fP on a program I expect to do *exactly* that (or use >>>>>> actual in-kernel capability inheritance, which I would find vastly >>>>>> more pleasant). If I give a program a capability (via fP or fI & pI), >>>>>> then I had better trust it not to abuse that capability. Having it >>>>>> pass that capability on to a child helper process would be just fine >>>>>> with me *because it already has that capability*. >>>>>> >>>>>> The problem with the current inheritance mechanism is that it's very >>>>>> difficult to understand what it means for an fI bit or a pI bit to be >>>>>> set. Saying "set a pI bit using pam if you want to grant permission >>>>>> to that user to run a particular program with fI set" is crap -- it >>>>>> only works if there is exactly one binary on the system with that bit >>>>>> set. In any case, a different administrator or package might use it >>>>>> for something different. >>>>>> >>>>>> Suppose I use the (apparently) current suggested approach: I install a >>>>>> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that >>>>>> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate >>>>>> validation of parameters. All is well. >>>>> Since you're writing a special helper, you can surely have it validate >>>>> the userid and make it so the calling user doesn't have to have >>>>> cap_net_raw in pI? >>>> I can and did. >>> Oh, oops, I mis-understood what you meant was the problem. >>> >>> Yup, that is a real limitation. >>> >>> Yes, with the posix file caps you will be disappointed unless you see >>> pI=X as "this user may run any program which is Inh-trusted with X" and >>> fI=X as "this program may be run with X by any user Inh-trusted with X". >>> >>> It almost makes me want to say that there should be an execve-analogue >>> to prctl(PR_SET_KEEPCAPS), which says caps will remain unchanged for one >>> execve. Or perhaps an intermediate securebits state between >>> !SECBIT_NOROOT and SECBIT_NOROOT, which automatically transitions after >>> the first execve to SECBIT_NOROOT. >>> >>>> The mere presence of a cap_net_raw+i tcpdump binary is more or less >>>> equivalent to saying that users with cap_net_raw in pI can capture >>>> packets. I've just prevented pI=cap_net_raw from meaning anything >>>> less than "can capture packets". So I think we should bite the bullet >>>> and just let programs opt in (via some appropriately careful >>>> mechanism) to real capability inheritance. >>> By real you mean more precise. I think it'd be very interesting to get >>> together with Markku and learn more from the N9 experiment! >>> >>> Markku, are there any post-mortem analysis papers we can read for >>> starters? Andy would not be trying to restrict root in general, so >>> the ramification you cited may not necessarily be relevant. >>> >>> -serge >> http://wt.tuxomania.net/publications/posix.1e/download.html >> >> Everyone should read the capabilities rationale. It answers most >> of the questions on this thread, and a bunch more. The capabilities >> mechanism has to support what are currently setuid-root programs >> without change and allow for new programs that use the mechanism >> wisely and fully. > How to put this delicately... that is not enjoyable reading :) It wasn't enjoyable writing, either! And the comment resolution process was ... long. > As I understood it, the draft supports setuid-root programs, but > does not support a !SECBIT_NOROOT environment. If that is not the > case, can you point to where in the draft that is described? The draft describes interfaces, not systems. This was how POSIX was set up, and specific use cases were explicitly beyond the scope of the document. The committee represented a number of vendors and the various uses were discussed, but by rule could not go into the document. So you're correct, the draft does not address the issue directly. It appeared that some of the arguments being made included assumptions about the behavior and derivation of Linux capabilities that were not accurate. I hope that providing the link helps some of the people who are unfamiliar with that. > > Regardless, > > 1. Andy describes a problem which AFAICT can't be solved with the > current capabilities support. An intermediate state between > !SECBIT_NOROOT and SECBIT_NOROOT (which itself is IIUC already an > extension beyond the above draft) seems an interesting feature to > consider which would support the wrapper case - but not something > to run into blindly without considering all the ramifications. > > 2. The N9 folks have experimented with other inheritence properties, > and the details their experience would be educational. > > There are two other ways the wrappered privileged tcpdump could be > achieved: > > 1. Have the privileged wrapper create a new user and network > namespace and pass the network device into the new network > namespace and run tcpdump there with privilege. This doesn't > work if the specific device also needs to be used in the original > network namespace (but passing a device bridged with the one of > interest might suffice?). > > 2. Have the privileged wrapper create a small tmpfs mount in a > (non-ms-shared) new mounts namespace, copy tcpdump into that mount > and give it fI=CAP_NET_RAW, then execute the child with > pI=CAP_NET_RAW. A bit hacky, but prevents the issue of other > users with pI=CAP_NET_RAW from executing that tcpdump. Since > the child will have pP=CAP_NET_RAW, the other users should be > prevented from getting to the modified tcpdump binary through > the child's /proc/pid/fd/N. > > Not saying these are ideal, just trying to think of ways of > solving the problem... > > -serge > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-07 14:42 ` Serge E. Hallyn 2012-12-07 17:00 ` Casey Schaufler @ 2012-12-07 17:07 ` Andrew G. Morgan 2012-12-07 18:39 ` Andy Lutomirski [not found] ` <CALQRfL6UWLFpTfvan9oirtLdozJqZX4oZwDuQFVnJp8MP06C_Q@mail.gmail.com> 2 siblings, 1 reply; 36+ messages in thread From: Andrew G. Morgan @ 2012-12-07 17:07 UTC (permalink / raw) To: Serge E. Hallyn Cc: Casey Schaufler, Serge Hallyn, Andy Lutomirski, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela I'm still missing something with the problem definition. So far if I follow the discussion we have determined that inheritance as implemented is OK except for the fact that giving user an inheritable pI bit which gives them default permission to use all binaries endowed with the corresponding file fI bit. Is this the problem a different inheritance model is supposed to address? Serge suggested that the binary could authenticate the user... This seems like its putting the protection in the best place... Each app can control its sub functions with the richest semantics. That being said... To me this looks like it's an access control problem... Namely use acls to limit which users (groups) can execute each privileged binary. Serge's option 2 seems like a similar approach. Cheers Andrew On Fri, Dec 7, 2012 at 6:42 AM, Serge E. Hallyn <serge@hallyn.com> wrote: > Quoting Casey Schaufler (casey@schaufler-ca.com): >> On 12/5/2012 2:20 PM, Serge Hallyn wrote: >> > Quoting Andy Lutomirski (luto@amacapital.net): >> >> On Wed, Dec 5, 2012 at 1:05 PM, Serge Hallyn <serge.hallyn@canonical.com> wrote: >> >>> Quoting Andy Lutomirski (luto@amacapital.net): >> >>>> On Tue, Dec 4, 2012 at 5:54 AM, Serge E. Hallyn <serge@hallyn.com> wrote: >> >>>>> Quoting Andy Lutomirski (luto@amacapital.net): >> >>>>>>>> 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. >> >>>>> But of course that is why you only want to fill fI on programs you trust >> >>>>> not to do that. What you are arguing is that you want to give fI on >> >>>>> programs you don't trust anyway, and so heck why not just give it on >> >>>>> everything. >> >>>>> >> >>>> Huh? I'd set fP on a program I expect to do *exactly* that (or use >> >>>> actual in-kernel capability inheritance, which I would find vastly >> >>>> more pleasant). If I give a program a capability (via fP or fI & pI), >> >>>> then I had better trust it not to abuse that capability. Having it >> >>>> pass that capability on to a child helper process would be just fine >> >>>> with me *because it already has that capability*. >> >>>> >> >>>> The problem with the current inheritance mechanism is that it's very >> >>>> difficult to understand what it means for an fI bit or a pI bit to be >> >>>> set. Saying "set a pI bit using pam if you want to grant permission >> >>>> to that user to run a particular program with fI set" is crap -- it >> >>>> only works if there is exactly one binary on the system with that bit >> >>>> set. In any case, a different administrator or package might use it >> >>>> for something different. >> >>>> >> >>>> Suppose I use the (apparently) current suggested approach: I install a >> >>>> fI=cap_net_raw copy of tcpdump somewhere. Then I write a helper that >> >>>> has fP=cap_new_raw and invokes that copy of tcpdump after appropriate >> >>>> validation of parameters. All is well. >> >>> Since you're writing a special helper, you can surely have it validate >> >>> the userid and make it so the calling user doesn't have to have >> >>> cap_net_raw in pI? >> >> I can and did. >> > Oh, oops, I mis-understood what you meant was the problem. >> > >> > Yup, that is a real limitation. >> > >> > Yes, with the posix file caps you will be disappointed unless you see >> > pI=X as "this user may run any program which is Inh-trusted with X" and >> > fI=X as "this program may be run with X by any user Inh-trusted with X". >> > >> > It almost makes me want to say that there should be an execve-analogue >> > to prctl(PR_SET_KEEPCAPS), which says caps will remain unchanged for one >> > execve. Or perhaps an intermediate securebits state between >> > !SECBIT_NOROOT and SECBIT_NOROOT, which automatically transitions after >> > the first execve to SECBIT_NOROOT. >> > >> >> The mere presence of a cap_net_raw+i tcpdump binary is more or less >> >> equivalent to saying that users with cap_net_raw in pI can capture >> >> packets. I've just prevented pI=cap_net_raw from meaning anything >> >> less than "can capture packets". So I think we should bite the bullet >> >> and just let programs opt in (via some appropriately careful >> >> mechanism) to real capability inheritance. >> > By real you mean more precise. I think it'd be very interesting to get >> > together with Markku and learn more from the N9 experiment! >> > >> > Markku, are there any post-mortem analysis papers we can read for >> > starters? Andy would not be trying to restrict root in general, so >> > the ramification you cited may not necessarily be relevant. >> > >> > -serge >> >> http://wt.tuxomania.net/publications/posix.1e/download.html >> >> Everyone should read the capabilities rationale. It answers most >> of the questions on this thread, and a bunch more. The capabilities >> mechanism has to support what are currently setuid-root programs >> without change and allow for new programs that use the mechanism >> wisely and fully. > > How to put this delicately... that is not enjoyable reading :) > > As I understood it, the draft supports setuid-root programs, but > does not support a !SECBIT_NOROOT environment. If that is not the > case, can you point to where in the draft that is described? > > Regardless, > > 1. Andy describes a problem which AFAICT can't be solved with the > current capabilities support. An intermediate state between > !SECBIT_NOROOT and SECBIT_NOROOT (which itself is IIUC already an > extension beyond the above draft) seems an interesting feature to > consider which would support the wrapper case - but not something > to run into blindly without considering all the ramifications. > > 2. The N9 folks have experimented with other inheritence properties, > and the details their experience would be educational. > > There are two other ways the wrappered privileged tcpdump could be > achieved: > > 1. Have the privileged wrapper create a new user and network > namespace and pass the network device into the new network > namespace and run tcpdump there with privilege. This doesn't > work if the specific device also needs to be used in the original > network namespace (but passing a device bridged with the one of > interest might suffice?). > > 2. Have the privileged wrapper create a small tmpfs mount in a > (non-ms-shared) new mounts namespace, copy tcpdump into that mount > and give it fI=CAP_NET_RAW, then execute the child with > pI=CAP_NET_RAW. A bit hacky, but prevents the issue of other > users with pI=CAP_NET_RAW from executing that tcpdump. Since > the child will have pP=CAP_NET_RAW, the other users should be > prevented from getting to the modified tcpdump binary through > the child's /proc/pid/fd/N. > > Not saying these are ideal, just trying to think of ways of > solving the problem... > > -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-07 17:07 ` Andrew G. Morgan @ 2012-12-07 18:39 ` Andy Lutomirski 2012-12-08 22:33 ` Andrew G. Morgan 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-07 18:39 UTC (permalink / raw) To: Andrew G. Morgan Cc: Serge E. Hallyn, Casey Schaufler, Serge Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Fri, Dec 7, 2012 at 9:07 AM, Andrew G. Morgan <morgan@kernel.org> wrote: > I'm still missing something with the problem definition. > > So far if I follow the discussion we have determined that inheritance > as implemented is OK except for the fact that giving user an > inheritable pI bit which gives them default permission to use all > binaries endowed with the corresponding file fI bit. This is IMO part of the problem but not the entire problem. > > Is this the problem a different inheritance model is supposed to > address? Serge suggested that the binary could authenticate the > user... This seems like its putting the protection in the best > place... Each app can control its sub functions with the richest > semantics. > > That being said... > > To me this looks like it's an access control problem... Namely use > acls to limit which users (groups) can execute each privileged binary. > Serge's option 2 seems like a similar approach. > The issue is (as I see it) with non-privileged binaries. If a given program (correctly) has a permitted capability and is not root, then the only way that it can pass that capability on to children (e.g. helper programs) is to set it into pI. This only works if the child has the same bit set in fI. This is doable but annoying -- every program that a privileged program runs needs to be authorized by the administrator. It breaks down because, currently, users with nonzero pI have no direct ability to wield the capabilities. That means that every single binary with fI bits set needs to be as careful as a setuid-root binary to avoid leaking privilege to the caller. (Obviously, binaries with fP set need to be careful. IMO binaries with only fI set should not need to exercise any particular care to defend themselves from their callers.) I'm obviously missing some fundamental (and probably historical) issue here, so let me ask the following straw-man question. Suppose capabilities worked like this on exec: pP' = pI | (fP & pB) (i.e. the current way, except that fI always has all bits set for every binary on the system) pI' = pI (unless !SECURE_NOROOT and uid == 0 or euid == 0, in which case pI' = pP') with the added restriction that pI is always a subset of pP (i.e. dropping a bit from pP (on exec or otherwise) drops that bit from pI). What would be wrong with this model? (Let's pretend for now that capabilities had always worked this way, so there's no change of behavior to worry about.) - The sendmail capability bug wouldn't happen: pI has no effect on setuid-root binaries. - There would be no difference between a user being trusted with a capability and being inh-trusted with that capability, since the latter concept wouldn't really exist. - Totally unprivileged users couldn't engage in any funny business. Their pI masks would be zero, and they would have no way of changing that. - Partially privileged users would work just fine. They could wield their capabilities (subject to some possible fiddling with pE) from bash or from anything else. They could also freely drop those capabilities. - Privileged programs would require less thought: to grant a program, you set its privilege in fP. There is no fI, so there's nothing special to think about. NB: This is not a real proposal because there *are* capability-aware programs out there. I want to understand why the current system is so different. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-07 18:39 ` Andy Lutomirski @ 2012-12-08 22:33 ` Andrew G. Morgan 2012-12-08 23:37 ` Andy Lutomirski 2012-12-10 14:36 ` Serge Hallyn 0 siblings, 2 replies; 36+ messages in thread From: Andrew G. Morgan @ 2012-12-08 22:33 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge E. Hallyn, Casey Schaufler, Serge Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Fri, Dec 7, 2012 at 10:39 AM, Andy Lutomirski <luto@amacapital.net> wrote: > On Fri, Dec 7, 2012 at 9:07 AM, Andrew G. Morgan <morgan@kernel.org> wrote: >> I'm still missing something with the problem definition. >> >> So far if I follow the discussion we have determined that inheritance >> as implemented is OK except for the fact that giving user an >> inheritable pI bit which gives them default permission to use all >> binaries endowed with the corresponding file fI bit. > > This is IMO part of the problem but not the entire problem. > >> >> Is this the problem a different inheritance model is supposed to >> address? Serge suggested that the binary could authenticate the >> user... This seems like its putting the protection in the best >> place... Each app can control its sub functions with the richest >> semantics. >> >> That being said... >> >> To me this looks like it's an access control problem... Namely use >> acls to limit which users (groups) can execute each privileged binary. >> Serge's option 2 seems like a similar approach. >> > > The issue is (as I see it) with non-privileged binaries. If a given > program (correctly) has a permitted capability and is not root, then > the only way that it can pass that capability on to children (e.g. > helper programs) is to set it into pI. This only works if the child > has the same bit set in fI. Yes. > This is doable but annoying -- every program that a privileged program > runs needs to be authorized by the administrator. Yes. > It breaks down because, currently, users with nonzero pI have no > direct ability to wield the capabilities. That means that every > single binary with fI bits set needs to be as careful as a setuid-root > binary to avoid leaking privilege to the caller. (Obviously, binaries > with fP set need to be careful. IMO binaries with only fI set should > not need to exercise any particular care to defend themselves from > their callers.) True. But what about protecting the system from privileges they didn't expect to have? > I'm obviously missing some fundamental (and probably historical) issue > here, so let me ask the following straw-man question. Suppose > capabilities worked like this on exec: > > pP' = pI | (fP & pB) (i.e. the current way, except that fI always has > all bits set for every binary on the system) > pI' = pI (unless !SECURE_NOROOT and uid == 0 or euid == 0, in which > case pI' = pP') > > with the added restriction that pI is always a subset of pP (i.e. > dropping a bit from pP (on exec or otherwise) drops that bit from pI). > > What would be wrong with this model? (Let's pretend for now that > capabilities had always worked this way, so there's no change of > behavior to worry about.) > > - The sendmail capability bug wouldn't happen: pI has no effect on > setuid-root binaries. Are you saying that setuid-root is required for a program like sendmail to work? Forever? > - There would be no difference between a user being trusted with a > capability and being inh-trusted with that capability, since the > latter concept wouldn't really exist. See below. It's key to see that it is not people, but programs that require privilege. > - Totally unprivileged users couldn't engage in any funny business. > Their pI masks would be zero, and they would have no way of changing > that. > > - Partially privileged users would work just fine. They could wield > their capabilities (subject to some possible fiddling with pE) from > bash or from anything else. They could also freely drop those > capabilities. > > - Privileged programs would require less thought: to grant a program, > you set its privilege in fP. There is no fI, so there's nothing > special to think about. > > > > NB: This is not a real proposal because there *are* capability-aware > programs out there. I want to understand why the current system is so > different. I think you have correctly determined a key difference (a fundamental feature!) of the model. For an explanation, please search for "key insight" in the OLS paper: http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf Also, see p310+ of the first document linked to on the page Casey pointed to: http://wt.tuxomania.net/publications/posix.1e/download.html which has quite an elaborate explanation of how this model was designed, and what the authors were trying to achieve. Cheers Andrew > > --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-08 22:33 ` Andrew G. Morgan @ 2012-12-08 23:37 ` Andy Lutomirski 2012-12-08 23:57 ` Andy Lutomirski 2012-12-10 14:59 ` Serge Hallyn 2012-12-10 14:36 ` Serge Hallyn 1 sibling, 2 replies; 36+ messages in thread From: Andy Lutomirski @ 2012-12-08 23:37 UTC (permalink / raw) To: Andrew G. Morgan Cc: Serge E. Hallyn, Casey Schaufler, Serge Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Sat, Dec 8, 2012 at 2:33 PM, Andrew G. Morgan <morgan@kernel.org> wrote: > On Fri, Dec 7, 2012 at 10:39 AM, Andy Lutomirski <luto@amacapital.net> wrote: >> It breaks down because, currently, users with nonzero pI have no >> direct ability to wield the capabilities. That means that every >> single binary with fI bits set needs to be as careful as a setuid-root >> binary to avoid leaking privilege to the caller. (Obviously, binaries >> with fP set need to be careful. IMO binaries with only fI set should >> not need to exercise any particular care to defend themselves from >> their callers.) > > True. But what about protecting the system from privileges they didn't > expect to have? I don't really understand. If I call rm -rf /, expect it to do nothing, but I inadvertently had CAP_DAC_OVERRIDE and passed it on, then I just shot myself in the foot. I don't see what this has to do with access control. > >> I'm obviously missing some fundamental (and probably historical) issue >> here, so let me ask the following straw-man question. Suppose >> capabilities worked like this on exec: >> >> pP' = pI | (fP & pB) (i.e. the current way, except that fI always has >> all bits set for every binary on the system) >> pI' = pI (unless !SECURE_NOROOT and uid == 0 or euid == 0, in which >> case pI' = pP') >> >> with the added restriction that pI is always a subset of pP (i.e. >> dropping a bit from pP (on exec or otherwise) drops that bit from pI). >> >> What would be wrong with this model? (Let's pretend for now that >> capabilities had always worked this way, so there's no change of >> behavior to worry about.) >> >> - The sendmail capability bug wouldn't happen: pI has no effect on >> setuid-root binaries. > > Are you saying that setuid-root is required for a program like > sendmail to work? Forever? No. If anyone writes a modern program like sendmail, it would be capability-aware and it wouldn't have the same problem. (And presumably it wouldn't use setuid(2), which is terminally broken.) > >> - There would be no difference between a user being trusted with a >> capability and being inh-trusted with that capability, since the >> latter concept wouldn't really exist. > > See below. It's key to see that it is not people, but programs that > require privilege. It may be key, but I am completely unconvinced that this is the right model. Windows has a capability system (called privileges, not capabilities) with full inheritance and no per-binary anything. It's worked just fine for decades, and it is completely immune to sendmail-like bugs because it *does not have* any concept of privileged binaries. It may have a classic MS-style overcomplicated APIs, but the model is quite simple and easy to understand. > I think you have correctly determined a key difference (a fundamental > feature!) of the model. > > For an explanation, please search for "key insight" in the OLS paper: > > http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf > > Also, see p310+ of the first document linked to on the page Casey pointed to: > > http://wt.tuxomania.net/publications/posix.1e/download.html > > which has quite an elaborate explanation of how this model was > designed, and what the authors were trying to achieve. I read the "key insight", although I admit that I gave up before I found page 310 of the old POSIX draft. (Why is the rationale nowhere near the beginning? I still can't figure out what the default value of fI is.*) I see no justification for *why* the authors were trying to achieve that. Again (any mainly because I feel like there's a giant mental disconnect here in that I really don't understand wtf the current / POSIX system is trying to accomplish): what would be wrong with a model in which capabilities could be freely passed from parent to child? Why would it be insecure? Why would it be error-prone? There's got to be *some* reason why it's not in use right now. I can speculate as to the reason the current scheme is barely used except internally to a few daemons (and why AFAIK there is no one making serious use of fI): it's basically incomprehensible. Security systems should be simple enough to understand and analyze. "Here is the set of things that I and my descendants can do" (the Windows model) is simple. "Here is the set of things I can do (pP). Here is a different set of things that a certain class of my descendants can do (pI). Here is the class of descendants that can do those things (fI). And here's a different class of descendants that can do things no matter who invokes them (fP)." is really hard to understand. It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" doesn't mean anything. Is he authorized to back things up to encrypted storage? Is he authorized to read any file for any purpose? Is he authorized to read things on behalf of properly authenticated remote users? No one knows because it depends entirely on what set of binaries with CAP_DAC_READ_SEARCH=i he can find. * I see "If pathconf() indicates that {_POSIX_CAP_PRESENT} is not in effect for a file, then the capability state of that file shall be implementation defined." I think this means that the designers didn't actually decide whether fI should default to all zeros or all ones. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-08 23:37 ` Andy Lutomirski @ 2012-12-08 23:57 ` Andy Lutomirski 2012-12-12 18:29 ` Andy Lutomirski 2012-12-10 14:59 ` Serge Hallyn 1 sibling, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-08 23:57 UTC (permalink / raw) To: Andrew G. Morgan Cc: Serge E. Hallyn, Casey Schaufler, Serge Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Sat, Dec 8, 2012 at 3:37 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > Again (any mainly because I feel like there's a giant mental > disconnect here in that I really don't understand wtf the current / > POSIX system is trying to accomplish): what would be wrong with a > model in which capabilities could be freely passed from parent to > child? Why would it be insecure? Why would it be error-prone? > There's got to be *some* reason why it's not in use right now. > > I can speculate as to the reason the current scheme is barely used > except internally to a few daemons (and why AFAIK there is no one > making serious use of fI): it's basically incomprehensible. Security > systems should be simple enough to understand and analyze. "Here is > the set of things that I and my descendants can do" (the Windows > model) is simple. "Here is the set of things I can do (pP). Here is > a different set of things that a certain class of my descendants can > do (pI). Here is the class of descendants that can do those things > (fI). And here's a different class of descendants that can do things > no matter who invokes them (fP)." is really hard to understand. > > It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" > doesn't mean anything. Is he authorized to back things up to > encrypted storage? Is he authorized to read any file for any purpose? > Is he authorized to read things on behalf of properly authenticated > remote users? No one knows because it depends entirely on what set of > binaries with CAP_DAC_READ_SEARCH=i he can find. > > * I see "If pathconf() indicates that {_POSIX_CAP_PRESENT} is not in > effect for a file, then the capability state of that file shall be > implementation defined." I think this means that the designers didn't > actually decide whether fI should default to all zeros or all ones. I just tried to search to find actual uses of pI/fI. Here's what I found: http://www.engardelinux.org/modules/index/list_archives.cgi?list=linux-security-module&page=0144.html&month=2010-04 A user (Stephen Hemminger, who presuambly understands Linux fairly well...) who gave up because normal programs couldn't inherit capabilities. http://fpmurphy.blogspot.com/2009/05/linux-security-capabilities.html Gives an (incorrect, AFAICT) example in which pI=cap_net_raw means "can ping" http://forums.fedoraforum.org/showthread.php?t=203879 An unanswered question which the poster thought (I think) that giving a user a capability would have some effect. OK, bored of this search now. Having trouble finding anything that works. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-08 23:57 ` Andy Lutomirski @ 2012-12-12 18:29 ` Andy Lutomirski 2012-12-12 18:45 ` Serge Hallyn 2012-12-19 13:14 ` Pádraig Brady 0 siblings, 2 replies; 36+ messages in thread From: Andy Lutomirski @ 2012-12-12 18:29 UTC (permalink / raw) To: Andrew G. Morgan Cc: Serge E. Hallyn, Casey Schaufler, Serge Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Sat, Dec 8, 2012 at 3:57 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > I just tried to search to find actual uses of pI/fI. Here's what I found: I downloaded all the Fedora spec files and searched for file capabilities. Assuming I didn't mess up, here's what I found: fping.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/fping fping.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/fping6 glibc.spec:%attr(755,root,root) %caps(cap_chown,cap_fowner=pe) %{_prefix}/libexec/pt_chown gnome-keyring.spec:%attr(0755,root,root) %caps(cap_ipc_lock=ep) %{_bindir}/gnome-keyring-daemon httpd.spec:%caps(cap_setuid,cap_setgid+pe) %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/clockdiff iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/arping iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep cap_net_admin=ep) %{_bindir}/ping iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep cap_net_admin=ep) %{_bindir}/ping6 mtr.spec:%attr(0755,root,root) %caps(cap_net_raw=pe) %{_sbindir}/mtr policycoreutils.spec:%caps(cap_setpcap,cap_setuid,cap_fowner,cap_dac_override,cap_sys_admin,cap_sys_nice=pe) %{_sbindir}/seunshare policycoreutils.spec:%attr(0755,root,root) %caps(cap_setpcap,cap_audit_write,cap_sys_admin,cap_fowner,cap_chown,cap_dac_override=pe) %{_bindir}/newrole rpm.spec:- fix double-free on %caps in spec (#877512) rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rcp rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rlogin rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rsh systemd.spec:%caps(cap_dac_override,cap_sys_ptrace=pe) %{_bindir}/systemd-detect-virt wireshark.spec:%attr(0750, root, wireshark) %caps(cap_net_raw,cap_net_admin=eip) %{_sbindir}/dumpcap xorg-x11-server.spec:%global Xorgperms %attr(0711,root,root) %caps(cap_sys_admin,cap_sys_rawio,cap_dac_override=pe) The only inheritable bit is on dumpcap, and it's not necessary there. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-12 18:29 ` Andy Lutomirski @ 2012-12-12 18:45 ` Serge Hallyn 2012-12-19 13:14 ` Pádraig Brady 1 sibling, 0 replies; 36+ messages in thread From: Serge Hallyn @ 2012-12-12 18:45 UTC (permalink / raw) To: Andy Lutomirski Cc: Andrew G. Morgan, Serge E. Hallyn, Casey Schaufler, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Andy Lutomirski (luto@amacapital.net): > On Sat, Dec 8, 2012 at 3:57 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > > > I just tried to search to find actual uses of pI/fI. Here's what I found: > > I downloaded all the Fedora spec files and searched for file > capabilities. Assuming I didn't mess up, here's what I found: > > fping.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/fping > fping.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/fping6 > glibc.spec:%attr(755,root,root) %caps(cap_chown,cap_fowner=pe) > %{_prefix}/libexec/pt_chown > gnome-keyring.spec:%attr(0755,root,root) %caps(cap_ipc_lock=ep) > %{_bindir}/gnome-keyring-daemon > httpd.spec:%caps(cap_setuid,cap_setgid+pe) > %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec > iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/clockdiff > iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep) %{_sbindir}/arping > iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep > cap_net_admin=ep) %{_bindir}/ping > iputils.spec:%attr(0755,root,root) %caps(cap_net_raw=ep > cap_net_admin=ep) %{_bindir}/ping6 > mtr.spec:%attr(0755,root,root) %caps(cap_net_raw=pe) %{_sbindir}/mtr > policycoreutils.spec:%caps(cap_setpcap,cap_setuid,cap_fowner,cap_dac_override,cap_sys_admin,cap_sys_nice=pe) > %{_sbindir}/seunshare > policycoreutils.spec:%attr(0755,root,root) > %caps(cap_setpcap,cap_audit_write,cap_sys_admin,cap_fowner,cap_chown,cap_dac_override=pe) > %{_bindir}/newrole > rpm.spec:- fix double-free on %caps in spec (#877512) > rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rcp > rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rlogin > rsh.spec:%attr(0755,root,root) %caps(cap_net_bind_service=pe) %{_bindir}/rsh > systemd.spec:%caps(cap_dac_override,cap_sys_ptrace=pe) > %{_bindir}/systemd-detect-virt > wireshark.spec:%attr(0750, root, wireshark) > %caps(cap_net_raw,cap_net_admin=eip) %{_sbindir}/dumpcap > xorg-x11-server.spec:%global Xorgperms %attr(0711,root,root) > %caps(cap_sys_admin,cap_sys_rawio,cap_dac_override=pe) > > The only inheritable bit is on dumpcap, and it's not necessary there. These are all cases of using caps to replace setuid-root. In itself this doesn't make the point you're aiming to make. At the same time I don't dispute that you may be right that almost noone is using fI the way we'd like. The reason I was in an earlier email laying out how a sudo-adm-like replacement could work is that I do think we're missing some userspace plumbing to make use of fI easier. We miss a tool to easily say "let joe use /usr/bin/X with caps Y". We miss a way for packaging tools to easily say "create a new user foo which has pI=xyz" and "install bar so that foo can run it with fI=xyz (by placing a copy under /var/lib/privs/foo). And we miss a one-liner for init scripts to launch services as a specific user that way. That still doesn't address the wrapper issue you raised, though it could lead to a design to solve it. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-12 18:29 ` Andy Lutomirski 2012-12-12 18:45 ` Serge Hallyn @ 2012-12-19 13:14 ` Pádraig Brady 1 sibling, 0 replies; 36+ messages in thread From: Pádraig Brady @ 2012-12-19 13:14 UTC (permalink / raw) To: Andy Lutomirski; +Cc: linux-kernel On 12/12/2012 06:29 PM, Andy Lutomirski wrote: > On Sat, Dec 8, 2012 at 3:57 PM, Andy Lutomirski <luto@amacapital.net> wrote: >> >> I just tried to search to find actual uses of pI/fI. Here's what I found: > > I downloaded all the Fedora spec files and searched for file > capabilities. Assuming I didn't mess up, here's what I found: Just pointing out a handy online search tool for this sort of thing. http://searchco.de/?q=%25caps+url:fedora+ext:spec thanks, Pǽdraig. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-08 23:37 ` Andy Lutomirski 2012-12-08 23:57 ` Andy Lutomirski @ 2012-12-10 14:59 ` Serge Hallyn 2012-12-10 15:47 ` Casey Schaufler 2012-12-10 18:05 ` Andy Lutomirski 1 sibling, 2 replies; 36+ messages in thread From: Serge Hallyn @ 2012-12-10 14:59 UTC (permalink / raw) To: Andy Lutomirski Cc: Andrew G. Morgan, Serge E. Hallyn, Casey Schaufler, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Andy Lutomirski (luto@amacapital.net): > It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" > doesn't mean anything. Is he authorized to back things up to > encrypted storage? We're talking about privileges at the kernel level here, and there is no way this could be expressed at that level. Higher level tools could/should certainly be exposing things at this level. BUT You *are* doing a good job of making me feel that we should have per-user fI xattrs or acls. Sudo is popular because people like to say "user joe can run foo with privilege". Most people will never want to be bothered to say "user joe can run foo with CAP_XYZ" (versus "as root"), but I do think we could get programs/packages to do that. Note that another difficulty here likes in the age-old, as yet unanswered imo, question of "how do I easily figure out what caps I need to run my program." A few years ago I pointed to this (perhaps in mostly private emails, don't recall) as something to be solved, but the solution escapes me. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 14:59 ` Serge Hallyn @ 2012-12-10 15:47 ` Casey Schaufler 2012-12-10 16:27 ` Serge Hallyn 2012-12-10 18:12 ` Andy Lutomirski 2012-12-10 18:05 ` Andy Lutomirski 1 sibling, 2 replies; 36+ messages in thread From: Casey Schaufler @ 2012-12-10 15:47 UTC (permalink / raw) To: Serge Hallyn Cc: Andy Lutomirski, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela, Casey Schaufler On 12/10/2012 6:59 AM, Serge Hallyn wrote: > Quoting Andy Lutomirski (luto@amacapital.net): >> It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" >> doesn't mean anything. Is he authorized to back things up to >> encrypted storage? > We're talking about privileges at the kernel level here, and there is > no way this could be expressed at that level. > > Higher level tools could/should certainly be exposing things at this > level. > > BUT > > You *are* doing a good job of making me feel that we should have > per-user fI xattrs or acls. Sudo is popular because people like to say > "user joe can run foo with privilege". Most people will never want to > be bothered to say "user joe can run foo with CAP_XYZ" (versus "as > root"), but I do think we could get programs/packages to do that. Put an ACL on the program file. If you want different users to run with different privilege make two copies of the program and give them different ACLs and cap sets. If your program is so big that making a copy is a disk space issue it is too big to have privilege. If you can't deal with having the have different paths for different users write a shell script that redirects to the correct version based on user id. This is not rocket science. The kernel shouldn't be crammed with mechanism and complexity just because disto/"OS"/site developers can't be bothered with learning how the existing facilities work. I frequently get requests to make changes to the way Smack controls access that can easily be achieved using users and groups. It's amazing how often people seem to forget that Linux has security mechanisms other than the one that they think is the cat's pajamas. > > Note that another difficulty here likes in the age-old, as yet > unanswered imo, question of "how do I easily figure out what caps I need > to run my program." A few years ago I pointed to this (perhaps in > mostly private emails, don't recall) as something to be solved, but > the solution escapes me. The audit trail is your friend. If it doesn't tell you what capabilities are required that you don't have, it should. Unfortunately, the Linux (formerly Unix) security policy into which the capabilities mechanism was retrofit is implementation derived. Without understanding how the Linux security system, with users and groups and LSMs and all works it's impossible to just guess and even if you do understand all that there is going to be lots of environmental context to deal with. Sorry, there's no magic wand. If I had it to do over there would be many fewer capabilities. Please reread that. I said fewer. You need something that would make SELinux policy look small to break out a consistent fine granularity, so I say go consistently coarse. > > -serge > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 15:47 ` Casey Schaufler @ 2012-12-10 16:27 ` Serge Hallyn 2012-12-10 18:12 ` Andy Lutomirski 1 sibling, 0 replies; 36+ messages in thread From: Serge Hallyn @ 2012-12-10 16:27 UTC (permalink / raw) To: Casey Schaufler Cc: Andy Lutomirski, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Casey Schaufler (casey@schaufler-ca.com): > On 12/10/2012 6:59 AM, Serge Hallyn wrote: > > Quoting Andy Lutomirski (luto@amacapital.net): > >> It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" > >> doesn't mean anything. Is he authorized to back things up to > >> encrypted storage? > > We're talking about privileges at the kernel level here, and there is > > no way this could be expressed at that level. > > > > Higher level tools could/should certainly be exposing things at this > > level. > > > > BUT > > > > You *are* doing a good job of making me feel that we should have > > per-user fI xattrs or acls. Sudo is popular because people like to say > > "user joe can run foo with privilege". Most people will never want to > > be bothered to say "user joe can run foo with CAP_XYZ" (versus "as > > root"), but I do think we could get programs/packages to do that. > > Put an ACL on the program file. > If you want different users to run with different privilege > make two copies of the program and give them different > ACLs and cap sets. Yes, but that is a bit kludgy. My own objection to doing per-user fI acls/xattrs is that it combines in the kernel what so far has only been mixed in userspace (uids and capabilities, mixed at pam_cap.so). I guess we could facilitate what you and amorgan suggest by having: 1. a database listing what privileges a particular tool needs for full functionality 2. a nice sudo-adm-like program which you can tell "let joe use X with full functionality. 3. the utility then keeps a hierarchy under /var/lib/privs/$user with binaries $user is allowed to use, properly set up with pI. No acl needed since /var/lib/privs/$user can just be perms 500. > If your program is so big that making a copy is a disk space issue > it is too big to have privilege. > If you can't deal with having the have different paths for different > users write a shell script that redirects to the correct version > based on user id. > > This is not rocket science. The kernel shouldn't be crammed > with mechanism and complexity just because disto/"OS"/site > developers can't be bothered with learning how the existing > facilities work. > > I frequently get requests to make changes to the way Smack > controls access that can easily be achieved using users and > groups. It's amazing how often people seem to forget that > Linux has security mechanisms other than the one that they > think is the cat's pajamas. > > > > > Note that another difficulty here likes in the age-old, as yet > > unanswered imo, question of "how do I easily figure out what caps I need > > to run my program." A few years ago I pointed to this (perhaps in > > mostly private emails, don't recall) as something to be solved, but > > the solution escapes me. > > The audit trail is your friend. If it doesn't tell you what > capabilities are required that you don't have, it should. I'm not asking how I personally could do it. I've written up the hard way to do it in papers before. I'm asking how a developer who just wants to let package installs of his program easily be privileged by certain users could make that happen. Asking him to go to the audit trail is (experience show) akin to telling him to use sudo or setuid-root. It's possible that good documentation is the (best, or only) answer. Or, I do think a cool program could be written which runs the target program in a container (with userns, so soon could be done unprivileged) sandbox, looks at audit and strace output with toggle-able capabilities. Taken to the extreme a debugger over a kernel in a vm could in fact be the magic want you say can't exist :) > Unfortunately, the Linux (formerly Unix) security policy into > which the capabilities mechanism was retrofit is implementation > derived. Without understanding how the Linux security system, > with users and groups and LSMs and all works it's impossible > to just guess and even if you do understand all that there is > going to be lots of environmental context to deal with. > Sorry, there's no magic wand. > > If I had it to do over there would be many fewer capabilities. > Please reread that. I said fewer. You need something that would make > SELinux policy look small to break out a consistent fine granularity, > so I say go consistently coarse. As I've said before, I think the way CAP_SYSLOG was introduced, although it was intended to be temporary, is the right way to add finer-grained capabilities: keep coarser capabilities which imply all the newer finer-grained capabilities which were derived. Similarly if we could come up with a nice hierarchy we could also come up with new, courser capabilities to combine similar existing ones (i.e. CAP_DAC_READ_SEARCH+CAP_DAC_OVERRIDE_CAP_FOWNER+CAPFSETID and CAP_SETUID+CAP_SETGID+CAP_SYS_NICE?) -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 15:47 ` Casey Schaufler 2012-12-10 16:27 ` Serge Hallyn @ 2012-12-10 18:12 ` Andy Lutomirski 2012-12-10 19:13 ` Casey Schaufler 1 sibling, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-10 18:12 UTC (permalink / raw) To: Casey Schaufler Cc: Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Mon, Dec 10, 2012 at 7:47 AM, Casey Schaufler <casey@schaufler-ca.com> wrote: > Put an ACL on the program file. > If you want different users to run with different privilege > make two copies of the program and give them different > ACLs and cap sets. > If your program is so big that making a copy is a disk space issue > it is too big to have privilege. > If you can't deal with having the have different paths for different > users write a shell script that redirects to the correct version > based on user id. > > This is not rocket science. The kernel shouldn't be crammed > with mechanism and complexity just because disto/"OS"/site > developers can't be bothered with learning how the existing > facilities work. I agree. But I think that the existing capability support is already overcomplicated, and I'd rather make it simpler. Sticking the complexity in userspace is too difficult right now because it requires fiddling with the file inheritable mask. I think that the Windows approach is worth looking at. See here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa375202%28v=vs.85%29.aspx In the Windows model, each capability ("privilege") can be in one of three states: enabled (i.e working right now), permitted (i.e. available upon request but not currently enabled), or removed (disallowed to this process and all of its children). Permitted privileges are always inherited when a child process is created. This is *way* simpler than Linux's model, and it works just fine*. --Andy * In fairness, MS apparently forgot to add the ability to drop permitted privileges until XP SP 2 or thereabouts. Adding it was a no-brainer, though, because Windows has no concept of setuid, so sendmail-style attacks are impossible even in principle. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 18:12 ` Andy Lutomirski @ 2012-12-10 19:13 ` Casey Schaufler 2012-12-10 19:31 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Casey Schaufler @ 2012-12-10 19:13 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela, Casey Schaufler On 12/10/2012 10:12 AM, Andy Lutomirski wrote: > On Mon, Dec 10, 2012 at 7:47 AM, Casey Schaufler <casey@schaufler-ca.com> wrote: >> Put an ACL on the program file. >> If you want different users to run with different privilege >> make two copies of the program and give them different >> ACLs and cap sets. >> If your program is so big that making a copy is a disk space issue >> it is too big to have privilege. >> If you can't deal with having the have different paths for different >> users write a shell script that redirects to the correct version >> based on user id. >> >> This is not rocket science. The kernel shouldn't be crammed >> with mechanism and complexity just because disto/"OS"/site >> developers can't be bothered with learning how the existing >> facilities work. > I agree. But I think that the existing capability support is already > overcomplicated, and I'd rather make it simpler. Sticking the > complexity in userspace is too difficult right now because it requires > fiddling with the file inheritable mask. > > I think that the Windows approach is worth looking at. See here: > > http://msdn.microsoft.com/en-us/library/windows/desktop/aa375202%28v=vs.85%29.aspx > > In the Windows model, each capability ("privilege") can be in one of > three states: enabled (i.e working right now), Effective > permitted (i.e. > available upon request but not currently enabled), Permitted > or removed > (disallowed to this process and all of its children). ~Inherited > Permitted > privileges are always inherited when a child process is created. > > This is *way* simpler than Linux's model, and it works just fine*. I see a different set of complications, and Windows never had a setuid bit to contend with. God created the universe in seven days, but then, He didn't have an installed base. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 19:13 ` Casey Schaufler @ 2012-12-10 19:31 ` Andy Lutomirski 2012-12-10 19:51 ` Casey Schaufler 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-10 19:31 UTC (permalink / raw) To: Casey Schaufler Cc: Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Mon, Dec 10, 2012 at 11:13 AM, Casey Schaufler <casey@schaufler-ca.com> wrote: > On 12/10/2012 10:12 AM, Andy Lutomirski wrote: >> I think that the Windows approach is worth looking at. See here: >> >> http://msdn.microsoft.com/en-us/library/windows/desktop/aa375202%28v=vs.85%29.aspx >> >> In the Windows model, each capability ("privilege") can be in one of >> three states: enabled (i.e working right now), > > Effective > >> permitted (i.e. >> available upon request but not currently enabled), > > Permitted > >> or removed >> (disallowed to this process and all of its children). > > ~Inherited No. It's ~Inherited in a world where every binary has fI = everything. > >> Permitted >> privileges are always inherited when a child process is created. >> >> This is *way* simpler than Linux's model, and it works just fine*. > > I see a different set of complications, and Windows never had > a setuid bit to contend with. God created the universe in seven > days, but then, He didn't have an installed base. > What are those complications? Also, I think we really could get rid of setuid without breaking anything with a bit of extra (non-capability-related) plumbing work. --Andy -- Andy Lutomirski AMA Capital Management, LLC ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 19:31 ` Andy Lutomirski @ 2012-12-10 19:51 ` Casey Schaufler 2012-12-10 19:55 ` Andy Lutomirski 0 siblings, 1 reply; 36+ messages in thread From: Casey Schaufler @ 2012-12-10 19:51 UTC (permalink / raw) To: Andy Lutomirski Cc: Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela, Casey Schaufler On 12/10/2012 11:31 AM, Andy Lutomirski wrote: > On Mon, Dec 10, 2012 at 11:13 AM, Casey Schaufler > <casey@schaufler-ca.com> wrote: >> On 12/10/2012 10:12 AM, Andy Lutomirski wrote: >>> I think that the Windows approach is worth looking at. See here: >>> >>> http://msdn.microsoft.com/en-us/library/windows/desktop/aa375202%28v=vs.85%29.aspx >>> >>> In the Windows model, each capability ("privilege") can be in one of >>> three states: enabled (i.e working right now), >> Effective >> >>> permitted (i.e. >>> available upon request but not currently enabled), >> Permitted >> >>> or removed >>> (disallowed to this process and all of its children). >> ~Inherited > No. It's ~Inherited in a world where every binary has fI = everything. > >>> Permitted >>> privileges are always inherited when a child process is created. >>> >>> This is *way* simpler than Linux's model, and it works just fine*. >> I see a different set of complications, and Windows never had >> a setuid bit to contend with. God created the universe in seven >> days, but then, He didn't have an installed base. >> > What are those complications? I wish I had the time to go into the details, but I just can't. > Also, I think we really could get rid of setuid without breaking > anything with a bit of extra (non-capability-related) plumbing work. If RedHat or Ubuntu wanted to take a year off from everything else they could create a setuid-root free system. It would probably be easier for Android or ChromiumOS, as they provide more limited environments. It's not "a bit of extra plumbing". I did it for a Unix system and you'll have to change bunches of existing programs to make it work. I'm not saying that the changes would be bad, but the sendmail fiasco arose from just such an effort. You'll also have to train the users that sudo no longer does them any good. In fact, you'll be barraged with one question: "How do I get to be Real root"? > --Andy > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 19:51 ` Casey Schaufler @ 2012-12-10 19:55 ` Andy Lutomirski 2012-12-10 20:17 ` Kees Cook 0 siblings, 1 reply; 36+ messages in thread From: Andy Lutomirski @ 2012-12-10 19:55 UTC (permalink / raw) To: Casey Schaufler Cc: Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Mon, Dec 10, 2012 at 11:51 AM, Casey Schaufler <casey@schaufler-ca.com> wrote: > On 12/10/2012 11:31 AM, Andy Lutomirski wrote: >> On Mon, Dec 10, 2012 at 11:13 AM, Casey Schaufler >> <casey@schaufler-ca.com> wrote: >>> On 12/10/2012 10:12 AM, Andy Lutomirski wrote: >>>> I think that the Windows approach is worth looking at. See here: >>>> >>>> http://msdn.microsoft.com/en-us/library/windows/desktop/aa375202%28v=vs.85%29.aspx >>>> >>>> In the Windows model, each capability ("privilege") can be in one of >>>> three states: enabled (i.e working right now), >>> Effective >>> >>>> permitted (i.e. >>>> available upon request but not currently enabled), >>> Permitted >>> >>>> or removed >>>> (disallowed to this process and all of its children). >>> ~Inherited >> No. It's ~Inherited in a world where every binary has fI = everything. >> >>>> Permitted >>>> privileges are always inherited when a child process is created. >>>> >>>> This is *way* simpler than Linux's model, and it works just fine*. >>> I see a different set of complications, and Windows never had >>> a setuid bit to contend with. God created the universe in seven >>> days, but then, He didn't have an installed base. >>> >> What are those complications? > > I wish I had the time to go into the details, but I just can't. Um. I'd like to solve what appears to me to be a problem. There's an existing design that, from my perspective, is overcomplicated and doesn't actually do what I want it to do. I'd really like to know what the current design *does* accomplish, since then I can make far more informed proposals for how to fix it. So far, I know of exactly nothing useful that's accomplished by the current design. It would be great if someone would enlighten me. > >> Also, I think we really could get rid of setuid without breaking >> anything with a bit of extra (non-capability-related) plumbing work. > > If RedHat or Ubuntu wanted to take a year off from everything else > they could create a setuid-root free system. It would probably be > easier for Android or ChromiumOS, as they provide more limited > environments. > > It's not "a bit of extra plumbing". I did it for a Unix system and > you'll have to change bunches of existing programs to make it work. > I'm not saying that the changes would be bad, but the sendmail > fiasco arose from just such an effort. You'll also have to train > the users that sudo no longer does them any good. In fact, you'll > be barraged with one question: > "How do I get to be Real root"? > That's not what I'm talking about. Write a daemon. Rig up wrappers for each setuid program to instead call into that daemon and have that daemon invoke the privileged program on behalf of the caller, with a sanitized environment. Be annoyed by a few items on the "linux plumber's wish list" that make this rather difficult right now. sudo would give real root, just like it does today. No setuid bit needed. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 19:55 ` Andy Lutomirski @ 2012-12-10 20:17 ` Kees Cook 0 siblings, 0 replies; 36+ messages in thread From: Kees Cook @ 2012-12-10 20:17 UTC (permalink / raw) To: Andy Lutomirski Cc: Casey Schaufler, Serge Hallyn, Andrew G. Morgan, Serge E. Hallyn, linux-kernel, linux-security-module, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Mon, Dec 10, 2012 at 11:55 AM, Andy Lutomirski <luto@amacapital.net> wrote: > Write a daemon. Rig up wrappers for each setuid program to instead > call into that daemon and have that daemon invoke the privileged > program on behalf of the caller, with a sanitized environment. Be > annoyed by a few items on the "linux plumber's wish list" that make > this rather difficult right now. FWIW, this is something we'd like to do in Chrome OS. Dealing with fs-attrs has traditionally been a pain, so this kind of simple passing down of privilege would be much nicer. It means we'd have a programmatic way to decide what privs a helper has, rather than having to represent it in some way on-disk. -Kees -- Kees Cook Chrome OS Security ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-10 14:59 ` Serge Hallyn 2012-12-10 15:47 ` Casey Schaufler @ 2012-12-10 18:05 ` Andy Lutomirski 1 sibling, 0 replies; 36+ messages in thread From: Andy Lutomirski @ 2012-12-10 18:05 UTC (permalink / raw) To: Serge Hallyn Cc: Andrew G. Morgan, Serge E. Hallyn, Casey Schaufler, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela On Mon, Dec 10, 2012 at 6:59 AM, Serge Hallyn <serge.hallyn@canonical.com> wrote: > Quoting Andy Lutomirski (luto@amacapital.net): >> It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" >> doesn't mean anything. Is he authorized to back things up to >> encrypted storage? > > We're talking about privileges at the kernel level here, and there is > no way this could be expressed at that level. > > Higher level tools could/should certainly be exposing things at this > level. Agreed, although selinux tries to allow this kind of detail in the kernel. I don't think capabilities should move in that direction. > > BUT > > You *are* doing a good job of making me feel that we should have > per-user fI xattrs or acls. Sudo is popular because people like to say > "user joe can run foo with privilege". Most people will never want to > be bothered to say "user joe can run foo with CAP_XYZ" (versus "as > root"), but I do think we could get programs/packages to do that. Hmm. I wish I was doing as good a job convincing myself that I know a good solution. I don't actually consider the fact that pI has insufficient granularity to be a problem in need of fixing. I think userspace can take care of detailed authorization questions on its own. I think the problem is that pI is failing to allow users who aren't root (or at least aren't uid=0) to have elevated, but not completely elevated, privilege. (If you don't like "users" in that sentence, feel free to replace it with "trusted programs that use execve as part of their operation".) Part of my struggle in proposing a solution is that there are two things I'd rather not add: 1. More modes. securebits, etc are hard to understand and can break assumptions that are currently true. 2. execve granting new privilege, even in the pI -> pP sense. There have been countless bugs relating to this in the past. This is why I proposed no_new_privs. A new mode that is only allowed when no_new_privs is set is considerably less dangerous, but still not wonderful. I could write a patch to add a new securebit SECURE_CAP_INHERITANCE that changes execve to act as though fI always contained all bits and to change capset to prevent pI from ever exceeding pP & pB. To make it usable without CAP_SETPCAP, maybe setting it to true should be legal without privilege if no_new_privs. (Actually, maybe all of the securebits should be freely tweakable if no_new_privs.) Some use cases: 1. Write a pam module that sets SECURE_CAP_INHERITANCE and assigns inheritable caps. Obviously it would grant users full use of those caps. The question is: what else would break? I.e. could users abuse it to exploit other setuid or fP!=0 binaries? 2. Write little fP != 0 helpers that check authorization, set no_new_privs and SECURE_CAP_INHERITANCE, and invoke something else. 3. (Pipe dream?) Eventually convince everyone to run in SECURE_CAP_INHERITANCE mode. I'll admit I'm not really thrilled by this suggestion. I'd like to do a survey and find out if anyone uses fI. If the answer is "no", fI support could be dropped in some kind of controlled manner, perhaps using the vfs cap version number. The setcap tool IMO wants some reworking anyway. --Andy ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [RFC] Capabilities still can't be inherited by normal programs 2012-12-08 22:33 ` Andrew G. Morgan 2012-12-08 23:37 ` Andy Lutomirski @ 2012-12-10 14:36 ` Serge Hallyn 1 sibling, 0 replies; 36+ messages in thread From: Serge Hallyn @ 2012-12-10 14:36 UTC (permalink / raw) To: Andrew G. Morgan Cc: Andy Lutomirski, Serge E. Hallyn, Casey Schaufler, linux-kernel, linux-security-module, Kees Cook, James Morris, Eric Paris, Serge E. Hallyn, Markku Savela Quoting Andrew G. Morgan (morgan@kernel.org): > > It breaks down because, currently, users with nonzero pI have no > > direct ability to wield the capabilities. That means that every > > single binary with fI bits set needs to be as careful as a setuid-root > > binary to avoid leaking privilege to the caller. (Obviously, binaries > > with fP set need to be careful. IMO binaries with only fI set should > > not need to exercise any particular care to defend themselves from > > their callers.) > > True. Uh, I disagree. Not true. (I suspect Andrew meant True to the first two sentences, not the last parenthesized one?) -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
[parent not found: <CALQRfL6UWLFpTfvan9oirtLdozJqZX4oZwDuQFVnJp8MP06C_Q@mail.gmail.com>]
* Re: [RFC] Capabilities still can't be inherited by normal programs [not found] ` <CALQRfL6UWLFpTfvan9oirtLdozJqZX4oZwDuQFVnJp8MP06C_Q@mail.gmail.com> @ 2012-12-10 14:27 ` Serge Hallyn 0 siblings, 0 replies; 36+ messages in thread From: Serge Hallyn @ 2012-12-10 14:27 UTC (permalink / raw) To: Andrew G. Morgan Cc: Serge E. Hallyn, Andy Lutomirski, Serge E. Hallyn, linux-security-module, James Morris, Markku Savela, Casey Schaufler, Eric Paris, Kees Cook, linux-kernel Quoting Andrew G. Morgan (morgan@kernel.org): > I'm still missing something with the problem definition. > > So far if I follow the discussion we have determined that inheritance as > implemented is OK except for the fact that giving user an inheritable pI > bit which gives them default permission to use all binaries endowed with > the corresponding file fI bit. There is another objection which ahs been raised, namely that it leaves too many tiny but crucial bits of security relevant information spread throughout the filesystem. This has also been said about using security.selinux xattrs. The answer as there could be a good set of tools to set and report the system wide state. In fact, libcap-ng provides such tools, to list the file capabilities throughout the system and capabilities in use by all running programs. -serge ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2012-12-19 13:14 UTC | newest] Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-12-02 3:04 [RFC] Capabilities still can't be inherited by normal programs Andy Lutomirski 2012-12-02 17:21 ` Andrew G. Morgan 2012-12-02 18:35 ` Andy Lutomirski 2012-12-02 22:26 ` Andrew G. Morgan 2012-12-02 23:04 ` Andy Lutomirski 2012-12-03 2:20 ` Andrew G. Morgan 2012-12-03 4:48 ` Andy Lutomirski 2012-12-04 13:54 ` Serge E. Hallyn 2012-12-05 19:32 ` Andy Lutomirski 2012-12-05 20:12 ` Markku Savela 2012-12-05 21:05 ` Serge Hallyn 2012-12-05 21:46 ` Andy Lutomirski 2012-12-05 22:20 ` Serge Hallyn 2012-12-07 0:57 ` Casey Schaufler 2012-12-07 14:42 ` Serge E. Hallyn 2012-12-07 17:00 ` Casey Schaufler 2012-12-07 17:07 ` Andrew G. Morgan 2012-12-07 18:39 ` Andy Lutomirski 2012-12-08 22:33 ` Andrew G. Morgan 2012-12-08 23:37 ` Andy Lutomirski 2012-12-08 23:57 ` Andy Lutomirski 2012-12-12 18:29 ` Andy Lutomirski 2012-12-12 18:45 ` Serge Hallyn 2012-12-19 13:14 ` Pádraig Brady 2012-12-10 14:59 ` Serge Hallyn 2012-12-10 15:47 ` Casey Schaufler 2012-12-10 16:27 ` Serge Hallyn 2012-12-10 18:12 ` Andy Lutomirski 2012-12-10 19:13 ` Casey Schaufler 2012-12-10 19:31 ` Andy Lutomirski 2012-12-10 19:51 ` Casey Schaufler 2012-12-10 19:55 ` Andy Lutomirski 2012-12-10 20:17 ` Kees Cook 2012-12-10 18:05 ` Andy Lutomirski 2012-12-10 14:36 ` Serge Hallyn [not found] ` <CALQRfL6UWLFpTfvan9oirtLdozJqZX4oZwDuQFVnJp8MP06C_Q@mail.gmail.com> 2012-12-10 14:27 ` Serge Hallyn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).