Hi! this is my first post here..
As you may imagine from the title I'm interested in microkernels at the moment, but there's one thing I still don't get:
all the docs I've read depict the microkernel as a minimal piece of code running at ring0 and handling all the lowest-level stuff (interrupts dispatching, memory management, scheduling and so forth..), on top of it, there are many *usermode* servers, which are responsible for most basic system services (for example a net_server, a file_server, a video_server, a printer_server et cetera),here is the problem: those servers, in order to work, need access to many hardware resources which can be accessed only through the kernel, but, on the other side, those servers are ordinary usermode apps, if this is the case, then every usermode program can potentially access hardware registers wreacking havoc in the system, but since mu-kernels are so famous for their stability and their ability to prevent core system components from kicking each other in the balls,there MUST be somewhere a mechanism to recognize if a given program has the necessary privileges to make a certain request to the kernel, but I've found anything about that until now. So my question is (sorry for being so long ::) ) how would you implement such a security mechanism ? could you give me some real-world examples with existing microkernels ?
thanks
Microkernel security
Re:Microkernel security
I am not far enough in os dev to be worrying about this yet, but I would image if you have kernel @ ring0, servers @ ring1 or ring2 and user programs @ ring3 the cpu would trap privledge violations for you... or maybe I have totally misunderstood what you are asking...
Cheers.
Cheers.
Re:Microkernel security
The best security model (that I'm aware of) is capabilities, unlike with most (or almost if not all) mainstream OSes programs simply inherit the permissions of the user running them, capabilities however divide the permissions up and allocate smaller sets to the individual program.
So for instance if I started a program which claimed to be a "mediaplayer" in it's headers, the kernel could allocate it a preset group of permissions (after making sure the user has them to give to the program to begin with) like: TCP_DOWNSTREAM, HAVE_GUI, VIDEO_ACCEL, FAST_DRAW, PLAY_SOUND, SOUND_ACCEL and FILE_READ[For its own installation folder only]. That would be about all a media player would need, so you can see that if the program crashed or got hacked, not a lot could go wrong. (You may notice I didn't include FILE_READ[Everything] since I'm assuming the file open dialog doesn't count, the user may freely select whatever they like, wherever they like using it)
This approach would go much the same with the servers, the server claims to be a "guiserver" so the kernel hands it IOCTL_VIDEO and perhaps a few more depending on whether your design requires permissions for messaging, reading its configuration file/registry entry and so on. (Note that the servers would most likely be started by the "System user" which represents the system before someone logs in and would have all the (low-level) capabilities so that the kernel can start and hand capabilities to the servers, a normal user could start a server provided they had START_SERVER as well as the required capabilities the server needs [naturally normal users would not have capabilities to talk directly to drivers])
You will probably not want to hardcode all these capabilities, so you could have a certain small set built in to the kernel but the rest are created by the servers dynamically (Give the servers CREATE_CAPABILITY) so that they can create their own capabilities as they start up (You can create them by string based names so that you don't rely on numerical identifiers from them being created in a particular order, or they can be grouped under the process id, etc). Naturally it would be risky leaving the service with CREATE_CAPABILITY so the service should surrender it once its done (If it fails to after X condition then kill it and destroy all the capabilities it made or simply revoke the capability so it can't use it again). [You will probably want a mechanism to verify the service is legitimate as well, you could simply use a boot script and assume it hasn't been tampered with or you can use code signatures and/or RAM Disks and so forth]
The above is just a general idea but Capabilities will probably be your most effective way to manage it, but there are probably more ways that someone else might be able to tell you about.
So for instance if I started a program which claimed to be a "mediaplayer" in it's headers, the kernel could allocate it a preset group of permissions (after making sure the user has them to give to the program to begin with) like: TCP_DOWNSTREAM, HAVE_GUI, VIDEO_ACCEL, FAST_DRAW, PLAY_SOUND, SOUND_ACCEL and FILE_READ[For its own installation folder only]. That would be about all a media player would need, so you can see that if the program crashed or got hacked, not a lot could go wrong. (You may notice I didn't include FILE_READ[Everything] since I'm assuming the file open dialog doesn't count, the user may freely select whatever they like, wherever they like using it)
This approach would go much the same with the servers, the server claims to be a "guiserver" so the kernel hands it IOCTL_VIDEO and perhaps a few more depending on whether your design requires permissions for messaging, reading its configuration file/registry entry and so on. (Note that the servers would most likely be started by the "System user" which represents the system before someone logs in and would have all the (low-level) capabilities so that the kernel can start and hand capabilities to the servers, a normal user could start a server provided they had START_SERVER as well as the required capabilities the server needs [naturally normal users would not have capabilities to talk directly to drivers])
You will probably not want to hardcode all these capabilities, so you could have a certain small set built in to the kernel but the rest are created by the servers dynamically (Give the servers CREATE_CAPABILITY) so that they can create their own capabilities as they start up (You can create them by string based names so that you don't rely on numerical identifiers from them being created in a particular order, or they can be grouped under the process id, etc). Naturally it would be risky leaving the service with CREATE_CAPABILITY so the service should surrender it once its done (If it fails to after X condition then kill it and destroy all the capabilities it made or simply revoke the capability so it can't use it again). [You will probably want a mechanism to verify the service is legitimate as well, you could simply use a boot script and assume it hasn't been tampered with or you can use code signatures and/or RAM Disks and so forth]
The above is just a general idea but Capabilities will probably be your most effective way to manage it, but there are probably more ways that someone else might be able to tell you about.
-
- Member
- Posts: 1600
- Joined: Wed Oct 18, 2006 11:59 am
- Location: Vienna/Austria
- Contact:
Re:Microkernel security
Roles for users of the OS are definitely a good thing. I imagine them to bi similar to what oracle assigns users in form of database roles.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
BlueillusionOS iso image
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Microkernel security
another that can be of help is the fact that, in most case, hardware resources can be delegated to user programs. For instance, you can easily have an application write directly to video memory if that application gets the video memory mapped in its own address space. Noone else can havoc with video.
That means if that application happens to be the GUI server, you're safe and happy
Under IA-32, you also can allow some I/O ports to be accessed by the application through the TSS's IO permission bitmap and IOPL field (oh, and for those who worry, IA-32 is one of the sole architecture to have a separated I/O space: other architectures are solely based on memory-mapped hardware
So once again, you can enable ports for the network card on the "network server" (and only on that server).
That means if that application happens to be the GUI server, you're safe and happy
Under IA-32, you also can allow some I/O ports to be accessed by the application through the TSS's IO permission bitmap and IOPL field (oh, and for those who worry, IA-32 is one of the sole architecture to have a separated I/O space: other architectures are solely based on memory-mapped hardware
So once again, you can enable ports for the network card on the "network server" (and only on that server).
Re:Microkernel security
Basically an issue of trust and identity. You wouldn't want to trust any userspace application to play fair with your hardware ressources, so you provide that trust only to those processes that properly identified themselves.
The rest is technicalities. Whether this identification is done via some capabilities mechanism, access controll lists, checksums of the binary image of the server verified upon loading it into memory... your architecture, your rules.
The rest is technicalities. Whether this identification is done via some capabilities mechanism, access controll lists, checksums of the binary image of the server verified upon loading it into memory... your architecture, your rules.
Every good solution is obvious once you've found it.