The MinorFs user-space filesystems works with AppArmor to provide a flexible form of discretionary access control.
Process Persistence

Programs are persistent; directories and files are persistent, but processes are not. This mismatch makes it impossible to add any persistent on-disk data storage to a process identified by a process ID, because when the process ends, the process ID is no longer valid. The base solution to allowing the OO-like abstractions at the process level of granularity for persistent on-disk storage is to define processes as an incarnation of a so-called pseudo-persistent process. So now, the program still will be equivalent to the class; the pseudo-persistent process is the persistent equivalent to the object, and the on-disk persistent directories and files are equivalent to member data fields. Using this new concept of a pseudo-persistent process gives us the ability to lift the disk data access-control features of AppArmor to a granularity level beyond what is possible with mandatory access control—that is, to the granularity of the pseudo-persistent process, but we don't have the burden of central or human administration, without the administrative overhead that mandatory access control embodies.

Pass by Reference

Where objects in OO languages can pass by reference, most IPC on Linux does not allow pass by reference between processes. One insightful exception to this that early UNIX engineers made was creating the ability of passing file handles over UNIX sockets. You could say that file handles used like this are fully pass by reference. In capability systems, such a reference is called a protected capability or an object capability.

Currently, directory file handles cannot be used as protected capabilities. To overcome this problem, there is a concept from capability-system history that is quite useful. The concept is to use a sparse key string as representation of the reference. That is, we create a relatively long sparse key string that both designates a resource and authorizes access to the resource. This string is called a sparse capability or unprotected capability. This type of capability is somewhat inferior to the protected type of which the UNIX file handle is an example. When combined with protection by AppArmor, it still has many properties that make its usage roughly equivalent to the usage of references in object-oriented languages.


AppArmor is the purely permissive mandatory access-control system used in SUSE and Ubuntu Linux. MinorFs uses AppArmor as its foundation, and in this way, it extends AppArmor so it can be used in a discretionary, even capability-based manner. Although MinorFs might be used separately from AppArmor, its usability is relatively limited. The main reason for MinorFs' limited usability without AppArmor is that by default, processes can access data (like the environment variables or command-line arguments) of other processes by way of the /proc/$PID directories, which (according to MinorFs' philosophy) should be considered private to the process.

This means without AppArmor, processes will, in some cases, be able to steal each other's capabilities through the proc filesystem. Although AppArmor fixes the vulnerabilities posed by the default proc filesystem access rights, MinorFs extends AppArmor. The access-control mechanism provided by MinorFs extends the static least-privilege approach that AppArmor offers with a dynamic least-authority approach. That is, it adds abilities to delegate decomposed and/or attenuated permissions.

The prime property of capability-based security that AppArmor helps us enforce is that processes should not have access to what would be equivalent to global variables. The temp and home directories in UNIX systems in many ways can be considered global variables if we look at them at the process level of granularity.

The way an AppArmor profile works is that it defines a list of permissions that are available for a specific application. For convenience, AppArmor also provides the ability to include sets of permissions with a single include directive.

When designing a system that will use MinorFs, you always should design your separation of privileges setup first. Don't allow your application to become a monolith.

Using AppArmor and MinorFs, you can build privilege-separated applications according to OO or capability paradigms, but even smaller steps can be quite useful. On installation, MinorFs creates a hard link to /bin/bash named /bin/minorbash that has the following AppArmor profile:

#include <tunables/global>

/bin/minorbash {
   #include <abstractions/base>
   #include <abstractions/bash>
   #include <minorfs/systemreadonly>
   #include <minorfs/full>

This profile basically gives a large set of read-only permissions but no write permissions to the version of bash named minorbash and to all programs started by it. This means, you simply can run programs with diminished access rights by starting them from a shell script that uses minorbash instead of bash.