An approach that is currently being investigated as part of the SPIN project is to trust the compiler to generate code that obeys the privilege restrictions. There are two possibilities for a kernel to trust the compiler. If the compiler is a stand-alone tool, as is usually the case, it has to ``sign'' the generated binary in such a manner that the kernel can be sure that only the trusted compiler could have generated this particular binary. This requires code in the kernel to verify the signature.
The second method is to make the compiler part of the operating system. One problem with the trusted compiler approach is that that the amount of trusted code grows significantly. The size of the Puma kernel, for which we are considering kernel extensions, is about 75 kB, while the size of a typical compiler is usually measured in mega bytes. Furthermore, the runtime systems of high-level languages can be large. For performance reasons, the runtime system has to stay resident in physical memory taking up valuable space.
In some sense, all operating systems trust the compiler that was used to compile them. With the trusted compiler approach the operating system places an additional kind of trust on the compiler. The operating system now assumes that the compiler not only produces correct code, but also code that does not violate the privilege restrictions. It is up to the compiler to reject code that might access memory that is accessible in kernel mode but not user mode.
For this approach, code insertion consists of linking the code into the kernel and, depending on whether the compiler is part of the operating system or not, verifying the identity of the code producer.