The core capabilities of our operating system (basically anything about process and thread management) are now well-defined. We can now fully envision separating our operating system in independent parts. But why did we choose this approach anyway ? For the sake of security, reliability, and adaptability. Security and reliability are compromised if processes can access all core features when they don’t need to (and, as an example, be granted access to any hardware). For that reason, there has to be a way of describing what a process needs the core to do and forbid it to ask for anything else. Let’s see how this works.
- Version independence : Even though I try to introduce a robust core architecture that’s not likely to need improvements once in a week, this is my first OS-related work and I’ve surely made some mistakes. Even senior OS developers make some and then feel the pain of having to redesign part of their OS. A way to somewhat ease this pain is to ensure independence between various parts of the OS. For that purpose, there won’t be bitmaps or other kinds of hard-coded security descriptors in this OS. There will be common rules for managing security things, and then parts of the core will have their own specific security clearances.
- A program is granted the right to do some things, not restricted the right to do others : We’ll give permissions to programs in order to do what they need to, we don’t forbid them to do what they don’t need to. This allows new features to be introduced at the core without needing to patch older programs that don’t use them.
- There must be room for generalizations and fuzzy logic : This is not needed at a core level, but will be needed when we move to more high-level things and target nontechnical peoples. Let’s picture it : you’re facing your computer. A video player asks memory page #12876f to be mapped in its memory. What would you do ? If you know some security basics, refuse when you don’t know what it is, and go look for it. But for that, you’ve got to know where to look for, and to understand what’s said there. So you’re technical people. There must be a way to group security permissions together in clearly labelled “tasks permissions” and to introduce imprecise permissions (like “permission to look at any file in folder schmurtz” instead of “permission to look at file x, file y, file z…”).
In process data, there’s room for some “clearances”. These are chunks of data managed by the core which tell “this process may make use of x system ability”. Like those magnetic cards you need to use in places full of paranoids.
Examples of clearances would be
-Create new threads
-Get more memory
-Handle some signals
A clearance must stay general-purpose. Hence “Create a maximum of 5 new threads” is not a good example, because the program may need more in the future, and then will have to create a new “Create a maximum of 7 new threads” clearance. Then the whole security model would have to be tweaked in order to manage it. That’s stupid.
To handle this, clearances will be able to include some data telling in more detail what they allow to do. In our example, the “Create new threads” clearance would include a “Maximum amount” parameter which tells how much threads may be created by the program. Trying to create more would result in a security failure. In the same way, permission to create files would include allowed folders, and so on.
And then, there’s the problem of grouping several security permissions together. Fortunately, modern object-oriented programming practices allows us to do that. We may as an example create a “general-purpose programs” security clearance that allows 100 threads to be created, 1 GB of memory to be reserved, and common exceptions to be managed. A check on this clearance for thread creation, memory reservation, and exception management would be positive.
USER SPACE ?
Can we put security management in user space ? The answer is both yes and no. A user process can not manage core-level security clearances, because it would be able to allocate itself extreme power and would hence made itself actually part of the core. For user-level security permission, it makes more sense, since it moves all the security-related work out of processes, since knowing if a process can do something is about asking security management to check its clearances, and managing ALL security permissions of the system cannot be done in the core without bloat and security weakness appearing.
However, clearances rely on process data, which is core data. So there should be core clearances allowing one to look at and modify non-core security clearances, which would be given to that security management process.
Since security is highly implementation-dependent, there’s little more to say now. More on that subject later, along with other implementation-dependent subjects, when the preceding parts of the core are implemented, up and running. For now, we’re going to start implementation of the system in the next articles.