Hi,
I'd like to merge the elad-kernelauth branch to the trunk
soon. This
mail should provide some clue about the work, and more
importantly, how
you can help.
1. Introduction
Kernel authorization was designed and developed by Apple.
It's a new
framework to handle all authorization requests inside the
kernel.
What are authorization requests? every time an operation
is made, for
now let's assume these are all privileged operations --
such as
mounting a file-system, or changing a process' user-id,
or attaching
ptrace to a process, or a special file-flag is set -- the
kernel
usually does one of two things:
- Checks if the user making that request is the
superuser by
calling the suser() routine with the user credentials
- Directly checks if the effective user-id of the
process is zero
While this held pretty nice in Unix-land for a while,
we're in a more
modern and complicated world today. Many of you might've
heard some
of the buzzwords in this field, such as "POSIX
capabilities" or Sun's
"process privileges"; some of you may even be
familiar with ACLs
and role-based access controls.
Implementing all of these require finer-grained
separation of each
request: who's making this request? what is the specific
operation
requested? under what context? etc.
Having the kernel authorization framework allows us to
have this
separation, and build on top of it.
For example, instead of simply checking if the user has
effective
user-id of zero, We issue a request for a specific
operation. We also
provide our credentials (more on this below), and perhaps
some
context.
The kernel authorization framework is divided to
"scopes". Each of
these is in charge of a different area in the system: we
can have the
process scope for handling process-related authorization
requests, a
vnode scope, a network scope, and so on.
Continuing with the above example, we issue the request
using the
authorization wrapper provided by the scope. Then, the
authorization
wrapper will dispatch our request -- with the credentials
and context
-- to the handlers associated with the scope. These
handlers are
referred to as "listeners".
Every scope has a default listener, but more listeners
can be
attached, allowing you to customize your system's
behavior. I'll give
an example for this later.
As I said above, we provide credentials to the
authorization
wrappers. It's worth noting that the credentials have
become an
opaque type: it's no longer possible to directly access
members like
"effective user-id" or "saved
group-id". In fact, there are very few
cases where you should be doing that. This opacity allows
us to
freely modify the credentials structure. One of the
side-effects is
that we just might implement a capabilities system! ;)
There's a lot more to it than just that, but let's keep
it simple,
for now. You can read more about kernel authorization, or
kauth for
short, at:
http://developer.apple.com/technotes/tn2005/tn2127.html
a>
An online reference to the kauth(9) man-page, describing
the
interface, can be found at:
http://www.
bsd.org.il/netbsd/kauth.9.html
But keep in mind that as this is still work-in-progress,
the
interface can still change.
2. NetBSD specific notes
Assuming we all have a slight clue about what kernel
authorization is
at this point, here are some notes regarding the NetBSD
implementation.
First, for now we're implementing only the
"process" and "generic"
scopes. There are also the "vnode" and
"fileop" scopes, used to
provide an interface to file-system ACLs and attaching to
file-related events respectively, but we haven't
implemented them
just yet. Of course, the real work was doing the
interface and
integrating it -- adding them is *probably* just a matter
of time.
To make things clear: we still don't have capabilities
or file-system
ACLs. While the first could be implemented using an
interface similar
to Solaris' ppriv(3) (dropping capabilities using system
calls), the
real benefit will be when we've added support for
extended attributes
in our file-system to associate these capabilities with
files
on-disk.
There's a SoC project for this one so if you think
you're capable you
should give it a shot; writing a (BSD-licensed!)
file-system that
supports journaling and extended attributes -- or
subfiles -- will
earn you unlimited fame and glory. ;)
Last but not least, keep in mind that the work that was
done so far
is merely integrating the kauth(9) interface. If you'll
take a look
at the code changes, you'll see that in some places we
end up
basically checking if the user-id is zero; make no
mistake, these are
just placeholders to make the merging less painful. This
is also
where *YOU* come into the picture. Read on...
3. What can *YOU* do
If it wasn't implied already, these are some big, heavy
changes to
the tree. True: most of these are mechanical, and I tried
to mimic
the exact behavior we have now, in order to have kauth(9)
transparently integrated. I've also stress-tested the
code on my
machines at home.
However... as with most stuff, breakage is usually to be
expected.
The code could still use some testing, especially in
configurations
that heavily utilize NFS or layared file-systems, for
example.
If it's not too much to ask, it would be *VERY* helpful
if people
could spend some of their time testing this branch a bit
before we
merge it.
To fetch the code from CVS, you should use:
cvs checkout -f -relad-kernelauth src
And then try to build a GENERIC kernel with the
DIAGNOSTIC option
uncommented. If you really feel crazy try DEBUG and
LOCKDEBUG..
Build a kernel and start using it... and report any
"anomalies" to
the list(s). Anomalies may include but are not limited
to:
- Unprivileged users can issue privileged operations
- Machine panics, crashes, or hangs, in situations it
didn't before
- Things that used to work now don't work; usually
with an
"Operation not permitted" (EPERM) error
So, again, if you have the time, *please* try it on your
own machine.
4. Example usage: securelevels
Those of you who follow tech-kern , saw I posted about
integrating
our securelevels with kauth(9) at some point. Here's a
little
breakdown of the hows and whats...
I'll assume we all know the BSD securelevel -- -1, 0, 1,
and 2, each
having its own meaning and implications. As great as it
may be, some
could argue that the powers-that-be who chose the
implications of
each level were doing something other than *B*SD. ;) In
fact, other
people may want to be able to use a custom set of
"knobs" from
different levels.
This is something we can easily use kauth(9) for. Due its
wonderful
pluggability (heh!) we're now in the position to let you
choose.
Each securelevel scheme we use -- and, at this point, we
should
really stop referring to the non-traditional scheme as
"securelevel"
-- has its own set of listeners. Switching schemes is as
easy as
uncommenting a kernel option, and what you get is that
the
authorization requests will be routed to a different
handler each
time.
If you choose the traditional scheme, you get what you
have now; and
the handlers simply check the security level to allow or
deny a
request. If you choose the other scheme, the request gets
to a
different handler, that checks for the specific knob in
charge of the
operation.
Same code all around the kernel, only different code for
the
listener. Simple, elegant, and clean. Exactly the
opposite of your
sex life.
5. Future directions
Unless it was obvious from the above, kauth(9) buys us a
lot of
granularity with regard to authorization and privilege
handling in
the kernel. It's the framework that makes it easy for us
to implement
features like capabilities, ACLs, and allows third-party
developers
to easily integrate their code with the NetBSD kernel
plugging on top
of existing authorization schemes, extending, modifying,
or changing
them entirely.
With time you'll see more and more development done in
this area: the
above mentioned securelevel changes will go first,
hopefully shortly
followed by capabilities, ACLs, and whatever ideas we --
or you --
have.
Remember that with your help we can get there faster! so
test,
comment, send feedback, and bring up new ideas (either in
public or
directly to me)
Thanks for your time and waiting for feedback,
-e.
--
Elad Efrat
|
> 3. What can *YOU* do
>
> If it wasn't implied already, these are some big,
heavy changes to
> the tree. True: most of these are mechanical, and I
tried to mimic
> the exact behavior we have now, in order to have
kauth(9)
> transparently integrated. I've also stress-tested
the code on my
> machines at home.
>
> However... as with most stuff, breakage is usually
to be expected.
> The code could still use some testing, especially in
configurations
> that heavily utilize NFS or layared file-systems,
for example.
>
> If it's not too much to ask, it would be *VERY*
helpful if people
> could spend some of their time testing this branch a
bit before we
> merge it.
>
> To fetch the code from CVS, you should use:
>
> cvs checkout -f -relad-kernelauth src
>
> And then try to build a GENERIC kernel with the
DIAGNOSTIC option
> uncommented. If you really feel crazy try DEBUG and
LOCKDEBUG..
>
> Build a kernel and start using it... and report any
"anomalies" to
> the list(s). Anomalies may include but are not
limited to:
>
> - Unprivileged users can issue privileged
operations
> - Machine panics, crashes, or hangs, in situations
it didn't before
> - Things that used to work now don't work;
usually with an
> "Operation not permitted" (EPERM)
error
>
> So, again, if you have the time, *please* try it on
your own machine.
>
>
Could you give some more hints on specific areas where you
made
changes so we can come up with some more direct tests? You
give some
hints about layered filesystems, but where else should we
look?
Just doing random stuff and waiting for failures isn't as
desirable.
Thanks,
_Matt
|