Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jan 1999 00:04:04 -0000
From:      Paul Richards <paul@originative.co.uk>
To:        freebsd-arch@FreeBSD.ORG
Subject:   RE: DEVFS, the time has come... 
Message-ID:  <E40CBF0361C7D111914000C0F0303D108865@OCTOPUS>

next in thread | raw e-mail | index | archive | help
Justin T. Gibbs writes:
> There is a chicken and egg problem with DEVFS and mounting root that
> Julian alluded to some time back having to do, I believe, with
> needing access to DEVFS before root is mounted, but this is a
> solvable problem.
> 
> If you agree that creating the nodes 000 and possibly even in the
> whiteout state is sufficient to safeguard the system, then there is
> no exploitable race.

I'd live with this situation but I still have reservations about a
daemon based solution.

>> From a robustness point of view, I'd be very concerned about
>> relying on a userland process for maintaining /dev. If that daemon
>> should not start or at some later point fall over then you may find
>> you have a hard time getting a useable system.
> 
> If the daemon doesn't start, you'll find yourself in single user
> mode and can use chmod/chown to manually arrive at a usable system.
> If the daemon dies after performing initial configuration, the worst
> case scenario is that persistence of chown/chgrp/etc. operations
> will be lost with a reboot and that you will have to perform manual
> operations for non-root users to see dynamic devices that have
> arrived after devd's death.  This does not seem unacceptable for a
> pathological situation.

If the daemon stops running for whatever reason then the admin might not
even realise it and be totally unaware that the policy changes will not
be applied upon reboot. A reboot may be many months away by which time
the policy change may have been completely forgotten about. This is a
good example of why I think the timing issues of applying the policy
change and having them become persistent are important to iron out. I
think POLA requires that a policy change be implemented forever more
once it is carried out and there be no risk that for some reason it does
not "stick". To be honest, I'd rather there be no persistence at all so
that at least people are aware of the issues than have a persistence
mechanism that has a possibility of failure.

I have definite reservations about a solution that relies on some agent
to sync up persistent policy with current state since if that sync up
doesn't occur security holes will crop up.

>> As a worst case scenario, should the on-disk
>> copy of the image get damaged in any way then at next boot you'll have a
>> totally screwed system, this is true of other binaries as well of course
>> but I think we should minimise such dependencies not increase them.
> 
> If we become really worried about these recovery scenarios, we can
> ship a modified MAKEDEV that can be run to provide standard
> permissions on extant nodes.  This should make it quite easy to get
> the system up far enough to restore or rebuild a working binary.

>> Personally, I can't see any way of preventing race conditions without    
>> applying policy when the device is created and that will require a
>> kernel implementation of persistence.
> 
> Before attempting to push a kernel implementation, please define the
> kinds of persistent information that can be recorded.  How much
> kernel bloat will it take to be able to specify policy for ranges of
> non-existent devices and how do you specify this policy?  I would
> want the full flexibility of regular expression matching to specify
> policy for dynamic devices.

That's probably the question we should have asked ourselves in the first
place :-)

I'm not advocating a solution that maintains the current mechanisms of
stating policy, i.e. I'm not a slave to POLA, if a totally new methodology
seems appropriate I think we should adopt it, in that case POLA doesn't
apply, it only applies when things seem the same but are subtly different
i.e. if it looks like /dev and chmod etc work then it'd better work exactly
as before. On the other hand, if we simply stop using those mechanisms
(chmod of files in /dev) for maintaining policy and require a totally
different mechanism to be adopted it doesn't break POLA. What I'm suggesting
is that we make /dev a static view of the kernel device information and
maintain that information via a totally different means. That way there is a
single source of policy rather than a transient source (current state of
dev) and a persistent source (some file maintained by a daemon/user).

Until a moment ago I was thinking that this would need a kernel based
database of device information since device events occur in the kernel but
it's just occurred to me that that doesn't have to be the case. If we accept
my opinion above, that /dev should be a static view and not a control
mechanism then we could enforce policy completely in userland by not having
the kernel drive events but only do the notification.

For instance:

At the moment the model we have is that devfs creates the view as the device
comes into existence and thereafter doesn't have any involvement.  Any
changes to /dev by the user after this event are done through the filesystem
using chmod etc and need to be recorded to achieve persistence and replayed
after the next reboot.

A totally different idea would be to limit kernel functionality to issuing
an event to a user process to signify the arrival of a device and then leave
the userland daemon decide what to do. It can look up a database and based
on that determine which instances of devfs will want to see this new device
and what name to use to create it as, even whether links should be
setup. Then it can issue a syscall to create the devices. Admin can be done
with another syscall to change device parameters.

If a device goes away then I think the kernel should do any clean up rather
than passing an event to the daemon since I can't see how the daemon could
do anything about other processes that have the device open. The kernel
should probably force a close and userland code would need to be cleaned up
to deal with the possibility of devices going away.

This would seem to satisfy a number of criteria from all sides.

Advantages:

The kernel implementation is minimal, passing an event to userland for
arrival of a new device. A syscall to create a device in devfs, a syscall to
change the properties of a device. There'd be no need to store any
information at all about policy in the kernel.

Policy changes are user driven and instantaneous, rather than kernel driven
or reliant on some user process providing synchronisation.  There'd be no
race conditions due to the kernel acting on events and the userland code
trying to catch up.

It would be trivial to build user tools to control devices since syscalls
would exist for easy manipulation. It would make developing graphical admin
tools etc much easier.

Another advantage of the filesystem as a static view methodology is that
devices can't be accidentally screwed by filesystem cockups i.e. a lame
admin doing a rm -fr in the wrong place can't harm the device view, similarly
for related filesystem accidents. These things do happen, protecting the
system from mistakes is a good thing IMO. To change device policy you'd have
to consciously make the effort to change the policy source.

If the daemon should die, you could still use a device control program
to change policy in a safe and consistent manner without having to worry
about fixing things up at a later reboot of ensuring consistency of
information in more than one source, which you would have to do with a
filesystem based policy method i.e. do the chmod then remember to update
the policy database so it happens after reboot.

Disadvantages:

A totally new way of implementing policy would be needed from admins since
manipulating the filesystem view of devices would no longer be possible.


Maybe this is a bit radical but it seems like a neat solution to the
problems.

Paul.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E40CBF0361C7D111914000C0F0303D108865>