Subject: Re: kauth, securelevel, and "run levels"
To: Elad Efrat <elad@NetBSD.org>
From: Thor Lancelot Simon <tls@rek.tjls.com>
List: tech-security
Date: 03/25/2006 16:51:27
On Sat, Mar 25, 2006 at 09:13:03PM +0200, Elad Efrat wrote:
> 
> > 2) We should implement, rather than this confusion of run-level and
> >    security-state in init, an ordered set of "run levels" implemented
> >    by init and the kernel cooperatively, so that if we're in "run level
> >    0", we know that everything's been killed off and init has started
> >    with a fresh slate.  Note that this would allow implementing intermediate
> >    or higher "run levels".  That's important.  See point 3.
> 
> Same as before, I ask you (or anyone else, for that matter) to provide
> what you think should be the implications of each "run level".

I think we're talking past each other, somehow.  I don't understand
what you want to know (that I didn't already describe), which is almost
certainly my own fault.  Could you elucidate?

Perhaps it is helpful to think of the current difference between
"single-user mode" and "multi-user mode".  These are, of course, two
different run levels.  What init does at the transition between them is
specified in the init manual page, but, to summarize:

On the "up" transition (from 0 to 1), init fires off a shell (which runs
the startup scripts in /etc/rc.d).  When that shell exits, init raises
the "security level" of the system.

So, for the "new model" I'm proposing, the only difference is "init
tells the kernel that we are entering 'run level 1', which causes
the kernel to load the 'run level 1' mask".

On the "down" transition, init waits for all other processes to exit.
After that, it lowers the "security level" of the system.  In the new
model, it would tell the kernel that the system is in "run level 0",
and the kernel would begin to enforce the "run level 0" mask.

At the moment, nothing prohibits root from using sysctl to set securelevel
to, say, 2, 3, 4, 5, 6, whatever.  But the only downwards transition _init_
knows about is from N > 0 to 0.  We could change that in the future, but
really, it is an implementation detail.  (Supporting orderly transitions
in the downwards direction between many run levels is hard to get right.
Let's discuss why _later_; it's not important _now_).  The kernel can
let init set the "run level" to whatever init cares to; the only rules
the kernel has to enforce are these:

1) The mask for level N can only be loaded into the kernel at level < N

2) Only init can lower the level.

3) On transition to level N, the kernel automatically applies the "level
   N" mask to all operations.

I think we could even go to "only init can raise the level" which might
make things cleaner; but init is somewhat ugly inside, and I can't really
think of much harm done by letting other processes _raise_ the level, so
that's something to think through further too, I guess.

-- 
  Thor Lancelot Simon	                                     tls@rek.tjls.com

  "We cannot usually in social life pursue a single value or a single moral
   aim, untroubled by the need to compromise with others."      - H.L.A. Hart