2011-07-26 - Phil Housley - undeconstructed @ gmail
This is a pre-proposal for a full OS, designed to fit within the ideals of the Gnome project. It actually isn’t Gnome specific in design, just in intention.
A successful Gnome OS would have to be:
The aim for this doc is to provide general mechanisms to achieve those characteristics, and to provide security and reliability through minimising attackable surfaces. Of course some flexibility is sacrificed to meet these goals, but hopefully this can be regained (as much as required) by adding controlled extension points, as opposed to allowing everything by default, and then attempting to add security where required.
This document takes a completely theoretical approach, with no immediate regard to practicality. In particular it expects very low cost message passing and context switching. You might spot several similarities with Android, but it’s supposed to be more generalised than those.
In a perfect world: I would start Gnome OS from scratch, with a modern microkernel. I would then implement all higher levels of functionality in lightweight virtual machines. There would be a well defined interface for those virtual machines to spawn child VMs, and to communicate, moderated by their parents (or spawners.) E.g. if two user apps, run by different users, want to communicate, they do so at the discretion of their parents (the user shells,) and their parent’s parents, up to their nearest common ancestor, the parent of all user applications. This hierarchy of VMs implements the basic access control mechanism for the system.
In an imperfect world: There isn’t anything described here that cannot be approximately implemented in a classical OS, it will just be more complicated to get the correct code running securely in each process, and there will be an extra abstraction layer between theory and practice. This is a compromise that I would not resist, since so much high quality free software already exists.
Aside: Why VMs? We are now at the point where VMs can match native code in most cases, via the mix of VM tech improvment, and the fact that most computers are currently over powered for most requirements. VMs increase safety, by allowing moderation of all application code, so trusted and untrusted code can be run in the same system, but with differing constraints.
The VM hierarchy provides an implementation of “contexts”. Traditionally, Unix shells have supported the idea of subshells, allowing arbitrary nesting of contexts that inherit from their parents. This was mostly lost in the GUI migration, where all apps run in basically then same context. In practice, this was not such a loss for most users, since subshells aren’t exactly convenient, plus existing shells don’t provide many management facilities to the user, or provide many resources to applications.
If the concept were fully fleshed out, then contexts would provide a full system for managing OS security, through to supporting multiple user level activities, baked right into the OS.
Process 1 in my Gnome OS would have the responsibility of spawning one new context (i.e, another VM, or equivalent) for each user. That context would spawn one shell for each login by the user, which could be CLI or GUI or anything else imaginable. The shells would launch applications, each in a new child context. Those applications would be able to communicate with the aid of their parents. Two sibling applications would talk through their shared parent, with only one permission check needed, but it would be no more complicated (for the developer) to communicate with apps run by the same user in other shells, since they are connected by the top level process for the user.
This concept extends in both directions. If an application wants to communicate with another user’s applications it can do so, provided all contexts up and then back down the hierarchy agree. Conversely, a user can spawn a new context within a shell, and then can trap applications within that context, by spawning new instances of those applications within the constraints of that context.
If an application wants to share resources between instances, it should spawn a server instance somewhere high in the hierarchy, and communicate with multiple clients elsewhere in the hierarchy, who will be able to discover it. This discovery will be done with a registry distributed through the context hierarchy, such that an application can simply pass up a request, and it will be intercepted by the first context in which it can be serviced. If needed, that context may spawn a server instance on demand. A sandboxed application will run in a context where all requests are quickly caught, and either blocked or emulated by the sandbox context.
With this communication system, it becomes possible to spawn many instances of an application without using excess resources, by using shared server processes. It also makes individual instances of an app more isolated, and provides a mechanism for multiple application instances that the app itself does not need to manage.
An application, if it is explicitly trusted to, can install more hooks into its parent context. This will allow the app to examine and potentially intercept messages as they pass through the context, and react to them as required, plus potentially other things, such as learning about new applications being spawned.
At the user level, contexts can be used directly as an organisational feature, with some UI assistance. A basic user might run only a single context in their shell, but an advanced user can run multiple contexts (subshells?,) for different tasks they perform. For example, a media player might run in a “background” context, to play music whilst you work. When you open an audio file in your “work” context, this will spawn a new instance of the player, and so not interfere with the music. These players may be allowed to communicate, so one can mute the other, but that will be at the discretion of the user. A powerful shell will allow easy switching between contexts, and configure itself according to what the user needs in the current context.
Anything that happens inside a context will be private unless otherwise stated. This would mean, for example, that an event tracker like zeitgeist could run independently in multiple contexts, completely dividing “personal” from “work”, or “projectA” from “projectB”. A browser could support different bookmarks, or a launcher show a different set of applications, or any application could support different configurations per context.
So far this document has been about the dynamic system. The other thing to consider is the static system, meaning basically the disc (or cloud?!) storage.
Storage will be assigned by default to match the dynamic system. There will be a storage area for context 1, in which the system is installed, equating to the current root fs. Each user’s head context will have its own virtualised storage area, which could be physically stored within the root, basically acting like the current home dir. Throughout the hierarchy, more virtualised stores will be created, so that any application instance has at least an empty file system available to it. Unlike the root and user file systems, these will be discarded on application exit (i.e. the end of the context), unless steps are taken to make them persistent.
Per-context stores will be able to map in parts of their parent stores, at the discretion of the parent context. This allows applications to access files from other contexts, when they have permission. This scheme also allows users to run instances of a single application in multiple contexts without interference, either by not supplying access to shared storage, or by mapping different physical locations to the same path in the virtual stores.
Some contexts will be made permanent by the user, meaning their virtualised stores will be persisted to disk. When this is done, an entire context can be serialised, to a secure section of its own virtual store. This means a context can be halted and relaunched on demand. A user who uses the same laptop at work and home can simply stop his “work” context on leaving the office, and restart it the next morning. With no major changes, contexts could even be transferred between computers without the applications being aware.
Application code will need to be made accessible to the context in which it is to be launched. Each application will be isolated on disc, or at least appear that way to the user. The application storage will be mapped into the context of the launching application, via mappings through parent contexts’ stores, in such a way that it can be launched but no more. Users may install applications locally in any persistent context, but these will not have access to the full range of permissions offered to administrator-installed applications.
The physical layout of the file system is actually fairly unimportant, since the user and most applications need only be aware of the logical mappings. The significant part is that there is at least some physical store associated with every context, i.e. with every application instance, and that this is isolated by default. Any stored data that combines information about multiple contexts (such as menus in a shell, providing access to all applications known to it) should be considered as configuration + cache, such that it can be rebuilt as the context hierarchy changes.
A context is therefore a combination of 1) dynamic: a running virtual machine, running application code, and 2) static: an isolated section of physical media, or equivalent. These two things together take the place of the previously rather nebulous idea of a program instance.
Clearly there’s no way I can hope to implement all of this, and so by myself, it would hardly be worth attempting. The main reason I’m writing this is because this is a direction for OSs that I would like to see explored, and I just hope it might be of interest to others, who are more able to achieve it than I am.
Finally, there are clearly lots of missing details here, but I know I can’t be comprehensive in a single document, and adding too much would simply provoke more questions than I have answers for at the moment.
Thanks for your time.