Subject: Re: representation of persistent device status, was Re: devfs, was Re: ptyfs...
To: der Mouse <mouse@Rodents.Montreal.QC.CA>
From: Thor Lancelot Simon <>
List: tech-kern
Date: 11/30/2004 15:06:52
On Tue, Nov 30, 2004 at 02:04:34PM -0500, der Mouse wrote:
> (I therefore assume you mean / is mounted ro.)

Yes, and thank you for pointing out various other typos/thinkos in
my hastily written message; AFAICT you noted them all correctly.

> > I can know that I _cannot_ have a problem with, for example, a new
> > device node for /dev/mem or /dev/wd0d popping up;
> It seems to me that what you want here is not nodev semantics as they
> exist but rather "no device nodes anywhere under this point", which
> means you need not only current "any device nodes here don't work"
> semantics but you also need to enforce the same flags on any mount
> whose mount point is under there (regardless of the filesystem type of
> the new mount).

Not exactly.  I want no _new_ device nodes anywhere on the system; not
just "not below here", but rather "not at all".  Requiring that all
writable filesystems have nodev set is a very simple and elegant way to
get that.  There are three ways to achieve that now:

1) Run at security level 2, which prohibits all new mounts.  This would
   still work with mandatory devfs, assuming devfs does *not* allow new
   nodes to be created after mount, and the boot-time configuration file
   is on a ro filesystem.

2) Run at the standard security level 1, but do not include MFS in the
   kernel, provide no device node for the raw device of the system disk,
   and ensure that all existing partitions are already mounted.

(Careful readers will note that I couldn't decide whether to give #1 or
 #2 as the example in my original message, and indulged myself in several
 stupid typos while switching from one to the other)

3) Make the simple kernel change I described earlier, such that no device
   node on any _writable_ filesystem can be used; that is, embed this
   policy in the kernel.

Mandatory devfs with a userland parser for the configuration file can
be used, carefully, with approach #1 above.  But AFAICT it totally
torpedoes #2 or #3.  That's unfortunate, because while #2 is fragile I
am aware of people using it now; and #3 is actually a very small code
change, seems to me quite elegant (and, after all, we do supply the OS
in source form!), and is much less fragile than #2 while much less
cumbersome than #1.

I'll also note that, in theory, it should be possible to achieve as
much protection from persistent compromise at security level 1 as at
security level 2 through judicious use of file flags rather than
wholesale reliance on read-only mounts and forbidding new mounts.  Without
any memory filesystem in the kernel, this is a viable approach -- though,
as you note, fragile -- which is why I don't personally use it.  But it
seems to me that devfs breaks this model completely, because it will
always be possible to hook up a new devfs, and there's no way to really
require that the config file have any particular attribute, whether
immutable, present on nodev filesystem, or _whatever_ -- unless the parser
is in the kernel, not userland.

That seems to me like a big problem.