Applying POLA to argument files and other files

We can divide the files that a process uses into two sets, Arg and Env. Arg is the set of files that are passed as parameters to the program. Env consists of the remaining files: libraries, configuration files, files that would be installed by a package manager -- files that the program is in some sense "linked with". Plash has always provided control over the Arg set, applying the Principle of Least Authority (POLA) to it. However, Plash has a default setting for the contents of the Env set. The use of executable objects lets you change that default on a per-program basis and apply POLA to all the files a program accesses.

By default, Plash maps the system's "/usr", "/lib", "/bin" and "/etc" directories (as read-only) into the file namespace of processes that it starts, along with "/dev/null" and "/dev/tty" (as read-write) -- this is the default Env set. Any other files or directories are mapped into the file namespace if and only if they are listed on the command line -- this is the Arg set.

In this default mode of operation, POLA is applied to files in the user's home directory, but not to system files. The programs you use do not have to be declared in advance. This way, Plash can be used almost as a drop-in replacement for non-POLA shells like Bash. You can run Unix programs using command lines that are not too different from their equivalents under Bash, because Plash's default Env set covers most of the program's actual Env set.

We can do a bit better if we are prepared to declare a program before using it, in order to provide some information about the program that is not provided in a Unix installation. Plash lets you create an executable object and bind it to a variable, specifying the Env portion of the program's file namespace. Given this control, you can include files that are not in Plash's default (such as configuration files in your home directory) or leave out files that are in Plash's default -- this helps get back the convenience of a non-POLA shell such as Bash while providing better security. Perhaps more importantly, you can control not only whether a filename is mapped in the namespace, but what file it maps to -- this provides something you couldn't do before.

It is possible to install two Linux distributions on one computer, and run one inside the other in a chroot() environment. However, the interoperability between these two sets of programs is very limited. Linux doesn't normally provide a fine-grained mechanism for granting a program access to files outside its chroot() environment, and the mechanisms for creating chroot() environments are limited: you can hard link files (but not directories, and not across partitions), and you can use "mount --bind" on directories (but not individual files). Furthermore, the chroot() call is only available to the superuser. It's difficult enough to use this for a couple of installed distributions; to do it on a per-program basis is totally impractical.

In contrast, Plash provides lightweight mechanisms for creating file namespaces (which are simply directories, although they do not have to be stored on a Linux filesystem). Executable objects can be self-contained and provide their own execution environment, which allows for better interoperability between programs: a process can invoke an executable object which uses a different file namespace (root directory) to the caller for files in its Env set, yet the executable object can receive its Arg set from the caller.