2006-09-11 21:28:29

by David Madore

[permalink] [raw]
Subject: capabilities patch: trying a more "consensual" approach

Hello again,

Given the rather cold reception that my "capabilities" patch has met,
it is obvious that it will never be accepted in any official kernel,
so I am now abandoning it and will try to suggest a different approach
that, in my opinion, isn't nearly as useful or expressive, but which
should probably be much more acceptable to those who found fault with
my previous patch, since it follows various suggestions which I
received on the list.

First, attempt to implement POSIX draft semantics for inheritance as
closely as the current situation will allow. (I think this is wrong,
but many people seem to care, and POSIX semantics is still better than
no semantics at all.) Actual filesystem support can come later (Serge
Hallyn has a patch for that), but in the meantime it would be useful
to add some (per-filesystem) mount options to specify the default
"inheritable" and "effective" capability sets. In the absence of this
mount option, the behavior would be entirely unchanged, so everyone
should be happy. With the mount options, capabilities will be
somewhat inheritable (only "somewhat", though, because with the POSIX
semantics, even with a default set, you can't force a non-caps-aware
process to gain caps in such a way that it will pass it on to its
children).

Second, suppress the idea of "regular" capabilities, and implement
them with Linux Security Module hooks (the module could be called,
say, "cuppabilities"). This won't do as much, but we can probably
still get a few things done that way. Unfortunately, the
cuppabilities won't (can't) follow the same inheritance rules as
capabilities, and this might be a bit confusing. But better than
nothing.

Is there some objection to this scheme? I should start coding it in a
couple of weeks.

Happy hacking,

--
David A. Madore
([email protected],
http://www.madore.org/~david/ )


2006-09-12 12:16:40

by Joshua Brindle

[permalink] [raw]
Subject: Re: capabilities patch: trying a more "consensual" approach

David Madore wrote:
> Hello again,
>
> Given the rather cold reception that my "capabilities" patch has met,
> it is obvious that it will never be accepted in any official kernel,
> so I am now abandoning it and will try to suggest a different approach
> that, in my opinion, isn't nearly as useful or expressive, but which
> should probably be much more acceptable to those who found fault with
> my previous patch, since it follows various suggestions which I
> received on the list.
>
> First, attempt to implement POSIX draft semantics for inheritance as
> closely as the current situation will allow. (I think this is wrong,
> but many people seem to care, and POSIX semantics is still better than
> no semantics at all.) Actual filesystem support can come later (Serge
> Hallyn has a patch for that), but in the meantime it would be useful
> to add some (per-filesystem) mount options to specify the default
> "inheritable" and "effective" capability sets. In the absence of this
> mount option, the behavior would be entirely unchanged, so everyone
> should be happy. With the mount options, capabilities will be
> somewhat inheritable (only "somewhat", though, because with the POSIX
> semantics, even with a default set, you can't force a non-caps-aware
> process to gain caps in such a way that it will pass it on to its
> children).
>
> Second, suppress the idea of "regular" capabilities, and implement
> them with Linux Security Module hooks (the module could be called,
> say, "cuppabilities"). This won't do as much, but we can probably
> still get a few things done that way. Unfortunately, the
> cuppabilities won't (can't) follow the same inheritance rules as
> capabilities, and this might be a bit confusing. But better than
> nothing.
>
> Is there some objection to this scheme? I should start coding it in a
> couple of weeks.
>
Do you have a practical use case for this? It still doesn't address the
questionable capabilities or the fact that the policy is embedded in the
processes all over the system and therefore there is no analyzable
system policy.

2006-09-15 22:52:19

by David Madore

[permalink] [raw]
Subject: Re: capabilities patch: trying a more "consensual" approach

Hi, Linux and LSM experts,

I would like to request some advice on how best to create an LSM for
creating underprivileged processes in a way that will seem acceptable
also to those Linux users and kernel hackers who don't want to hear
about it (i.e., my patch should not mess more than necessary with the
rest of the kernel).

In a nutshell, the goal is to do this: when the module is loaded, each
task should have a "cuppabilities" variable, which is initially blank
and, when certain bits are added to it (or removed, depending on your
point of view), prevents certain system calls from succeeding. This
variable should be inherited across fork() and exec(), and some
interface should be provided to add more cuppabilities (i.e., make a
process less-than-normally privileged).

Now, if I understand correctly, the various alloc_security() LSM hooks
do not stack well: if I want my module to be stackable after SElinux
(and I do), I can't hook task_alloc_security() to create my variable,
so I need to store these "cuppabilities" in a globally visible task
field. Do I understand correctly? How acceptable is this? (We can
assume that 32 bits will be wide enough, so I'm not talking about
adding huge amounts of data to the task struct.)

Second, what would be the cleanest and most acceptable way to provide
an interface to these new "cuppabilities"? For example, should I add
a new, dedicated, system call? If so, should I provide new hooks to
it in struct security_operations? Or is, perhaps, prctl() a better
path (then I would have to request a hook on that in SElinux)? How
can I best avoid breaking causing any disruption to the rest of the
kernel?

Any advice is welcome.

Happy hacking,

--
David A. Madore
([email protected],
http://www.madore.org/~david/ )

2006-09-18 12:58:15

by Stephen Smalley

[permalink] [raw]
Subject: Re: capabilities patch: trying a more "consensual" approach

On Sat, 2006-09-16 at 00:52 +0200, David Madore wrote:
> Hi, Linux and LSM experts,
>
> I would like to request some advice on how best to create an LSM for
> creating underprivileged processes in a way that will seem acceptable
> also to those Linux users and kernel hackers who don't want to hear
> about it (i.e., my patch should not mess more than necessary with the
> rest of the kernel).
>
> In a nutshell, the goal is to do this: when the module is loaded, each
> task should have a "cuppabilities" variable, which is initially blank
> and, when certain bits are added to it (or removed, depending on your
> point of view), prevents certain system calls from succeeding. This
> variable should be inherited across fork() and exec(), and some
> interface should be provided to add more cuppabilities (i.e., make a
> process less-than-normally privileged).
>
> Now, if I understand correctly, the various alloc_security() LSM hooks
> do not stack well: if I want my module to be stackable after SElinux
> (and I do), I can't hook task_alloc_security() to create my variable,
> so I need to store these "cuppabilities" in a globally visible task
> field. Do I understand correctly? How acceptable is this? (We can
> assume that 32 bits will be wide enough, so I'm not talking about
> adding huge amounts of data to the task struct.)

No, I think that is a losing strategy, and it defeats the purpose of
having LSM in the first place. For now, I'd suggest just _not_
supporting stacking with SELinux until such a time as you've
successfully gotten your module merged, then later you can take up the
best way to support such stacking (whether via direct modification of
SELinux to enable chaining off of its security structures, or via the
"stacker" module previously implemented by Serge that lacks a real
motivating user, although that is contentious).

> Second, what would be the cleanest and most acceptable way to provide
> an interface to these new "cuppabilities"? For example, should I add
> a new, dedicated, system call? If so, should I provide new hooks to
> it in struct security_operations? Or is, perhaps, prctl() a better
> path (then I would have to request a hook on that in SElinux)? How
> can I best avoid breaking causing any disruption to the rest of the
> kernel?

For SELinux, we had to drop our syscall and re-implement the API via:
- /proc/pid/attr for process attributes (getprocattr and setprocattr
hooks)
- xattr API for file attributes,
- selinuxfs (pseudo filesystem) for control and other operations. These
days you would use securityfs (it didn't exist at the time selinuxfs was
created).

--
Stephen Smalley
National Security Agency

2006-09-19 23:08:22

by Pavel Machek

[permalink] [raw]
Subject: Re: capabilities patch: trying a more "consensual" approach

Hi!

> Is there some objection to this scheme? I should start coding it in a
> couple of weeks.

Looks okay to me.
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2006-09-22 03:42:19

by Crispin Cowan

[permalink] [raw]
Subject: Re: capabilities patch: trying a more "consensual" approach

Stephen Smalley wrote:
> On Sat, 2006-09-16 at 00:52 +0200, David Madore wrote:
>
>> Now, if I understand correctly, the various alloc_security() LSM hooks
>> do not stack well: if I want my module to be stackable after SElinux
>> (and I do), I can't hook task_alloc_security() to create my variable,
>> so I need to store these "cuppabilities" in a globally visible task
>> field. Do I understand correctly? How acceptable is this? (We can
>> assume that 32 bits will be wide enough, so I'm not talking about
>> adding huge amounts of data to the task struct.)
>>
> No, I think that is a losing strategy, and it defeats the purpose of
> having LSM in the first place. For now, I'd suggest just _not_
> supporting stacking with SELinux until such a time as you've
> successfully gotten your module merged, then later you can take up the
> best way to support such stacking (whether via direct modification of
> SELinux to enable chaining off of its security structures, or via the
> "stacker" module previously implemented by Serge that lacks a real
> motivating user, although that is contentious).
>
I mostly agree with Stephen. I agree with both the approach of modifying
SELinux so that its task security blobs chain to yours, and I agree with
the suggestion of letting Stacker do it. I also suggest you consider the
inverse stack of making your module stack with SELinux instead of vice
versa (chain in the opposite order) and I suggest you consider making
your module stack with AppArmor.

The only part I question is why you would need to wait for your module
to start development on any of these approaches. Especially the Stacker
approach.

On that point, now that LSM is staying, and there are a multitude of
modules proposed for mainstream, perhaps it is time to reconsider
merging Stacker. There was a *lot* of effort invested there benchmarking
various schemes. With multiple modules coming in, and stacking a
recurring problem, perhaps we need it now.

Crispin

--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
Hack: adroit engineering solution to an unanticipated problem
Hacker: one who is adroit at pounding round pegs into square holes