Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Reading kext resources in the kernel (Was: Saving persistent data from kernel?)




On May 2, 2005, at 7:23 AM, John Dalgliesh wrote:
On Sun, 1 May 2005, Mike Smith wrote:
On Apr 30, 2005, at 8:11 AM, John Dalgliesh wrote:

You can trust the daemon when it is root, because root can do
anything.

That's not trust, but it highlights exactly what's *wrong* with
running as root.

... later ...

Right again.  Because a degree of trust is implicit in running as root,
and the system only wants things that are trusted running as root.

Surely you see there is a contradiction there? I agree with the second
statement not the first. Running something as root implies that it is
trusted. And sometimes you will require something to be run as root to
prove its trustworthiness to the system.

Speaking for the system, I don't want anything doing work as root that
does not *need* to run as root.

A firmware uploader for a device driver does not need to run as root
if the image can be validated.

If it is implemented inside the driver, it must run as root.  If it is
implemented in a daemon/helper application, it can (and ideally should) 
run as someone other than root.

Note that if you run the helper as, e.g. daemon/daemon, it is not possible
to become that user without having been privileged at some point.

This guards you against uploads by arbitrary users, but does not require
that the uploader actually run with privilege.  It's a much better way to 
go about it.

If you have a daemon helper for your kext, it doesn't have to run as
root.

That way, the system does not have to trust it.  Instead, it's forced
to trust your kext even though it does not want to.

I'm glad at least that you view running a daemon as root to be the same as
putting code in a kext. Now we can drop the whole 'don't do that in the
kernel' thread of the argument and focus on the trust issue.

No, I don't, and I can't see how you get there from here.

From a trust standpoint, code running in a kext is worse than a
daemon running as root, which is worse again than the daemon
running as some other user.

In this example, the principle of least privilege applies.

I see a major problem with making a kext depend on anything external. The
more complicated it is, the worse the dependency. The problem is that
having an external dependency _extends your trust to that dependency_.
Even when it is just giving you data, you have to trust that data. The
tracking of tainted data in perl is a concrete example of this thinking.

Ultimately you are trusting the filesystem; in other words, your
protection only extends to the point that you assume that an
attacker has never had privilege. 

In order to trust your uploader, you do not need for it to have privilege,
merely to demonstrate that at some point it had it.

Speaking for the system, again, I would be much happier to know
that a trusted system component with privilege started your
uploader in a without-privilege state.  Your trust requirements
are met with the overall use of least privilege.

There's no point trying to split a driver up into trusted and untrusted
parts, if that weakens the security of the whole by depending on (and
thereby trusting to some extent) the so-called 'untrusted' part.

On the contrary, again we look to the principle of least privilege.

Code goes into the kernel, or runs as root, because it *requires* 
that privilege.  If it doesn't require one or the other, it should not.

There's nothing that a straightforward loader does that requires 
privilege.

Again, this is why as much code as possible should run untrusted, and
why you should do your file I/O in a daemon that is *not* running as
root.

So how do you explain the design of the NVRAM module then?

The NVRAM module has no ability to examine the semantic impact
of the data it's being passed.  Thus it requires a straight _expression_
of trust on its caller.  Since the interface is used interactively, this
maps best to requiring the caller to be root.

Conversely, since your firmware image is protected by the filesystem, 
the uploader is started by a trusted component and obtains a token
(a reserved uid/gid) of same, root privilege is not required and thus 
should not be used.

And surely the funky virtual memory and kernel threads that make up
the Darwin kernel environment alleviate some of the deadlock/design
concerns?

That's a great design approach: "it's complicated, surely it must
work".  8)

My point was not that it was complicated. My point was that the kernel
environment is very much like the process environment.

And the point I have been trying to make all along is that is *not*.

I understand that you think that because you have something called "open"
and a function out of <vnode_internal.h> that looks like "read" and
"write", you have userland-like semantics.

vnode_open( char * name, mode, &ptr );
vnode_unlock( ptr );

You shouldn't do this; the vnode comes to you ready to use.  What led you to
believe it needed to be unlocked?

vn_rdwr( READ, ptr, buf, size, offset, flags );

Did you plan on closing it at some point?

Not being allowed to run your daemon as root is the huge and important
issue.

It's not really the issue you make it out to be.

Another problem with not running as root: What if the driver has to run
before any user logs in? One of the uses of my drivers is for internet
access via satellite. I can easily imagine a scenario with one machine
providing the access for a small network. A user should not be required to
log on to start up network services on that machine.

You don't have to have someone logged in for a daemon to run as non-root;
many of the system daemons run this way.

And anyway, which user should it be if not root?

daemon:daemon would be a good start.

A startup item is not appropriate for hot pluggable drivers such those
for PCMCIA cards (and USB/FireWire boxes, but they don't have quite the
same trust issues).

A startup item works just fine.  It starts, then waits for the device to show up.
When it shows up and the driver attaches, it uploads the firmware to the
driver.

This involves:

1) No daemon running with privilege
2) No file I/O inside the kernel
3) No route to compromising the firmware image without having privilege
4) Less code within the kernel
5) A simple, modular design

 = Mike

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-drivers mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/darwin-drivers/email@hidden

This email sent to email@hidden

References: 
 >Re: Saving persistent data from kernel? (From: Mike Smith <email@hidden>)
 >Reading kext resources in the kernel (Was: Saving persistent data from kernel?) (From: John Dalgliesh <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.