Page 1 of 1

drivers

Posted: Tue Aug 10, 2004 12:44 am
by lucas
Does kernel mode drivers really run in ring 0?

If so, they certainly have the power to wreak havoc!
(whether they are buggy , malicious or harmless)

So i thought of putting them at ring 1 or 2 and each of them in separate address space.

Re:drivers

Posted: Tue Aug 10, 2004 1:21 am
by lucas
anyone has any comments about that?

Re:drivers

Posted: Tue Aug 10, 2004 1:43 am
by Candy
often thought about, but nobody really cared.

If your driver has access to any ports it can wreak havoc anyway. Consider a keyboard driver that can use the keyboard interface to manually reset the system.

Why bother shielding off one half if you leave the other wide open?

If you do care, consider reading about microkernels, they place the bulk of the driver(s) at ring 3.

Re:drivers

Posted: Tue Aug 10, 2004 1:45 am
by Pype.Clicker
that really depends on the driver ... and on the OS. In linux, drivers run at level 0 and become part of the kernel. Microkernels prefer to have their drivers in separate address spaces.

Note that a few things the drivers do *need* to occur at level 0, like responding to IRQs etc. The real question is what trust you put in your driver writer. You probably expect kernel-shipped drivers to work "as well" as the kernel core...

Re:drivers

Posted: Tue Aug 10, 2004 1:52 am
by Candy
Pype.Clicker wrote: Note that a few things the drivers do *need* to occur at level 0, like responding to IRQs etc. The real question is what trust you put in your driver writer. You probably expect kernel-shipped drivers to work "as well" as the kernel core...
I think you can make the IRQ start up a non-L0 thread / code segment call. The point of protection is lost however, since things such as cli/sti/port output to any ports (even if they're yours) is very unsafe in client code. They defeat any security but they have to be used for some code. There is no way to win.

Re:drivers

Posted: Tue Aug 10, 2004 2:14 am
by Legend
Tell the driver applications via IPC that an IRQ has happended, this will receive the IRQ in ring 0 (in your kernel I guess), but the real processing happens in ring 3.

Use an I/O bitmap to limit the amount of ports each individual driver can use. cli/sti? Hopefully a driver won't need that on it's own.

Perhaps the keyboard controller that can reboot the computer is a bad thing - design weakness in the computer.

However, you can protect yourself for example from the sound driver, network card driver, graphics card driver etc.

And don't forget that Linux does TCP/IP in the kernel, too, which directly does not need any hardware access, so it would already be better to get that on ring 3.

Re:drivers

Posted: Tue Aug 10, 2004 2:41 am
by Brendan
Hi,
Legend wrote: Tell the driver applications via IPC that an IRQ has happended, this will receive the IRQ in ring 0 (in your kernel I guess), but the real processing happens in ring 3.

Use an I/O bitmap to limit the amount of ports each individual driver can use. cli/sti? Hopefully a driver won't need that on it's own.

Perhaps the keyboard controller that can reboot the computer is a bad thing - design weakness in the computer.

However, you can protect yourself for example from the sound driver, network card driver, graphics card driver etc.

And don't forget that Linux does TCP/IP in the kernel, too, which directly does not need any hardware access, so it would already be better to get that on ring 3.
This is almost exactly how my OS does it :)

I don't use an IO port bitmap though, instead the IO instructions generate a general protection fault, and the GPF handler emulates the IO port instruction. In this way I can stop the keyboard driver from rebooting the computer.

The only area where a malicious/buggy driver can trash something is bus mastering devices that transfer data directly into physical memory (except for the ISA DMA controller which is controlled/protected by the kernel). It's impossible to protect the OS from this regardless of what you do.


Cheers,

Brendan

Re:drivers

Posted: Tue Aug 10, 2004 6:28 am
by Pype.Clicker
Legend wrote: Tell the driver applications via IPC that an IRQ has happended, this will receive the IRQ in ring 0 (in your kernel I guess), but the real processing happens in ring 3.
Agree, this can be done... however, you will dramatically decrease the throughput you can achieve on the device. Take for instance the disk driver. If you're able to emit the next "read sector" command right after being notified of the previous command completion, you're working at higher speed.

With a ring-3 driver, you'll have to wait for at least one context switch before this can be done (assuming that you don't have in addition to wait for some process to complete its execution before you get the notification)
However, you can protect yourself for example from the sound driver, network card driver, graphics card driver etc.
possibly, yes, though those drivers may have some 'DMA' programming features, and if you submit corrupted data to the DMA registers, you'll screw up your system's memory ... You can hardly enforce checks on this without a knowledge of the device at kernel-level
And don't forget that Linux does TCP/IP in the kernel, too, which directly does not need any hardware access, so it would already be better to get that on ring 3.
Indeed, TCP/IP doesn't need hardware access. However, it's a demultiplexing component towards several processes, thus having it as a user process would imply additionnal switch.

Concerning my own project, i'm trying to put reasonnable amount of work at kernel level and keep the "gross" job as user-level. This means for instance that IP forwarding would occur at user-level but that user-mode could have the opportunity to install filters for kernel-level NIC driver so that the kernel-level code can know (without understanding the whole TCP/IP stack) who's the packet recipient.