From: Jeff D. <jd...@ka...> - 2000-03-14 19:13:33
|
I replied privately (by accident) with this: It is possible right now for a hostile process to break out of the user-mode virtual machine and gain access to the hosting machine. However, this is fairly easy to fix. It would not be hard to turn the virtual machine into a secure jail. > It's essentially a software sandbox; a safe place to play with > untrusted apps. I plan to write an article for LinuxMonth expanding > on that idea and showing how to do it. It is good for that, since a hostile program would have to specifically attack the kernel. I don't think many such attacks have been implemented since uml is still fairly new... > one could still not use it to directly gain root in the host OS. Right. You're root inside, but outside you're just a normal user. So something that manages to break out goes from being root inside to being unpriviledged outside. > I believe I remember reading that when a disk sector is being > requested, the rest of uml is held up The block driver is completely synchronous at this point. I don't know how this affects performance, but it probably doesn't help. > and the idle thread tends to soak up a lot of CPU time It busy-waits, just like any normal idle thread. I'm planning on using the kernel's APM support to turn the busy-waiting into sleeping. This will make uml put a lower load on the system. > The ultimate way to accomplish this would be to have all a shared, > read-only filesystem with all the files that no-one needs to write to > and a much smaller writeable root with symlinks for directories and > writeable /var, /tmp, /etc, etc. directories. Each uml mounts its own > writeable root and this shared space. That's a decent idea. I was thinking about some kind of an overlay filesystem to do the same thing. > Jeff - if the file on the host OS is read-only for the user running > UML, can I mount it read-only in UML? That would seem like a > reasonably secure way of making sure none of the umls can corrupt or > modify the shared filespace. Yes. What one kernel must not do is mount a device that another kernel has mounted read-write. He's talking about sticking bind in a uml, which could work well. It's not like a million-hit-per-day web server. Jeff |
From: Jeff D. <jd...@ka...> - 2000-03-14 22:37:35
|
la...@no... said: > In Linux/a386, I just replaced the asm("hlt") with > a386_interrupt_wait(), which sleeps until woken up by a signal or > until the next timer interrupt (aka SIGTVALRM) would have occurred. That's more or less what I'm planning. What complicates things is I'd have to have the input thread start delivering signals to sleeping idle threads when there's some input to handle, and that's racy. This will be especially handy with MP emulation. Currently, you'll have 2 or 4 (or whatever) idle threads all spinning when they have nothing to do. Jeff |
From: Jeff D. <jd...@ka...> - 2000-03-15 06:42:35
|
> If you decide _not_ to finish the migration to jail, I'd sincerely > love to hear about where those holes in the razor wire even _might_ > exist; it'll make the article more useful. It's definitely on my list. I just haven't done anything about it yet. Big hole #1: The tracing thread's stack is in kernel physical memory. All a hostile process needs to do is zero it out or something, and the tracing thread crashes. Since it was ptracing the hostile process and intercepting its system calls, once it's gone, the hostile process is no longer under control. It now has access to the host system (as whatever user ran the kernel, not as root). Big hole #2: When a process is running process code, its system calls are intercepted. When it is running a system call or trap handler in the kernel, they are not. There is a field in the thread structure which keeps track of this. A hostile process could locate its kernel stack (at the bottom of which is its task structure, which contains the thread structure), and flip that field to fake the tracing thread into believing that its system calls are not to be intercepted. It now has access to the host system. All of the other attacks that I can think of which involve corrupting kernel data also involve crashing the kernel without letting the attacking process out of jail. That's not good, but it's not terrible, especially if the jail is just for that one process. Jeff |
From: lars b. <la...@no...> - 2000-03-14 19:22:01
|
Jeff Dike <jd...@ka...> writes: > > and the idle thread tends to soak up a lot of CPU time > It busy-waits, just like any normal idle thread. I'm planning on using the > kernel's APM support to turn the busy-waiting into sleeping. This will make > uml put a lower load on the system. In Linux/a386, I just replaced the asm("hlt") with a386_interrupt_wait(), which sleeps until woken up by a signal or until the next timer interrupt (aka SIGTVALRM) would have occurred. |
From: William S. <wst...@po...> - 2000-03-14 23:27:56
|
On Tue, 14 Mar 2000, Jeff Dike wrote: > It is possible right now for a hostile process to break out of the user-mode > virtual machine and gain access to the hosting machine. > > However, this is fairly easy to fix. It would not be hard to turn the > virtual machine into a secure jail. > > > It's essentially a software sandbox; a safe place to play with > > untrusted apps. I plan to write an article for LinuxMonth expanding > > on that idea and showing how to do it. Interesting; I hadn't realized that. While there might be situations where it would be fun to migrate an app back and forth between uml and host (I can't think of any, but that doesn't mean there aren't any), I would personally have a preference that uml be a self contained locked down environment. I see some real use as a sandbox environment. If you decide _not_ to finish the migration to jail, I'd sincerely love to hear about where those holes in the razor wire even _might_ exist; it'll make the article more useful. > It is good for that, since a hostile program would have to specifically attack > the kernel. I don't think many such attacks have been implemented since uml > is still fairly new... I suppose the obvious points of attack would include any place where ./linux trusts information provided inside uml and acts on that information in the host OS. Unfortunately, it means that ./linux probably _shouldn't_ allow a user in uml to assign the IP address to be used in the host OS; one might have a certain amount of fun by assigning 127.0.0.1 to umn. :-) previous post, Bill: > The ethertap could be brought up once during host system boot and left > until uml-linux is started. Just for example: Boot scripts bring up > tap0 w/ 192.168.0.254, ptp -> 192.168.0.253, and add a route to .253. > /dev/tap0 is given mode 660, owned by root/uml-group. previous post, Jeff: If you're doing serious network stuff, you'd want a bunch of them, and I'd be somewhat concerned about potentially locking out other ethertap users. Also, the fact that both ends are configured a boot time before a uml runs means that the uml net setup scripts need to change to just accept whatever IP address the uml's /dev/tap has. It also means that the IP address needs to be read out of the network driver somehow and fed back into ifconfig so that the network layer knows its own IP address. The administrator of the system would be responsible for allocating as many as would be needed ahead of time and providing routing table entries to the uml's on the other ends of the taps. In fact, each uml can be told which tap to connect to, which would be the tap that has the right routing table for that uml. I still think that passing: ./linux tap0=192.168.0.253,/dev/tap12 is elegant enough that the uml can know what to open in the host OS and what IP address to assign to it's own tap. If this turns out to be a useful approach, I'd be glad to help with the documentation for the host OS side of it too. Have I missed something in the uml environment? You seem to be referring to telling umn/tap12 in uml what IP address it has. Does it really need to know at that low a level? Couldn't umn/tap12 simply act promiscuous (or the pointopoint equivalent) and pass everything up to the network layer so that the network layer could decide what needs to be handled locally? I understand that ifconfig in uml needs to know what IP address to assign to the interface, but that could be handed in on the kernel command line. previous post, Bill: > The right to access host networking is now down to whether ./linux is > able to read and write to a preconfigured /dev/tap0. Is that a more > elegant approach? previous port, Jeff: It's better, but I'm not all that happy with it. What security problems arise from letting normal users set the ptp address (assuming that address isn't already used) of an otherwise configured /dev/tap and letting them send and receive packets over it? That's what I'd really like to be able to do. I don't think the unprivileged user would need to set anything on the host tap0. All of the taps could have the same address (much like having the same remote address on a terminal server for 253 dialup users), and individual routes to the uml IP's could be set, one through each host tap. Since the addresses are being allocated ahead of time to allow the routes to be put in place, the ptp addresses could be set at that time as well. I don't particularly like the idea of preallocating network devices that may not be used either. If we don't, however, either ./linux has to be given special privileges or the user needs special rights to make those changes. I'd rather see the devices preconfigured and left to sit until used. > > The ultimate way to accomplish this would be to have all a shared, > > read-only filesystem with all the files that no-one needs to write to > > and a much smaller writeable root with symlinks for directories and > > writeable /var, /tmp, /etc, etc. directories. Each uml mounts its own > > writeable root and this shared space. > > That's a decent idea. I was thinking about some kind of an overlay filesystem > to do the same thing. Jeff, if you can code a true union filesystem that could someday be part of the mainstream kernel, I would be forever in your debt. I wrote a long list of uses that could have, not the least of which back then and here too would include the ability to mount a writeable small ext2 partition on top of a readonly cdrom or readonly root_fs. I'm quite serious - that would be fantastic and would be truly useful even outside of uml. > > Jeff - if the file on the host OS is read-only for the user running > > UML, can I mount it read-only in UML? That would seem like a > > reasonably secure way of making sure none of the umls can corrupt or > > modify the shared filespace. > > Yes. What one kernel must not do is mount a device that another kernel has > mounted read-write. Agreed - they'd all have to be RO. > He's talking about sticking bind in a uml, which could work well. It's not > like a million-hit-per-day web server. True! Cheers, - Bill --------------------------------------------------------------------------- "``Threads are like salt. You like salt, I like salt, but we eat a lot more pasta than salt.'' The thread guys are trying to tell you that diet of salt is a good idea. They are wrong, don't listen, eat more pasta and be happy." -- Larry McVoy <lm...@bi...> -------------------------------------------------------------------------- William Stearns (wst...@po...). Mason, Buildkernel, named2hosts, and ipfwadm2ipchains are at: http://www.pobox.com/~wstearns LinuxMonth; articles for Linux Enthusiasts! http://www.linuxmonth.com -------------------------------------------------------------------------- |