[cap-talk] powerboxed device drivers; language-based or OS based capablities?

Matej Kosik kosik at fiit.stuba.sk
Mon Jan 22 09:15:12 CST 2007


Is it completely bad to not to use capability languages for writing
operating system kernels?

There are two ways to go:
1. OS capabilities
2. language-based capabilities

The first can be useful for composing systems written in any language.
The security policy is then enforced via mechanisms provided by the
operating system and the hardware supported processes are treated as a
whole. This naturally leads to microkernel-based operating systems.

The latter approach offers different advantages. We can create a single
monolithic kernel (all its parts must then be written in a single
capability-secure language) without security problems usually connected
with this architecture. I have made a small experiment


in which I have created VGA driver which is given all the authority it
needs but not more.

Language-based security is someout outside the scope of those mechanisms
with are provided by Intel (or other hardware company) and actually free
us. It is very easy to enforce any descriptable security policy this
way. Thus, when some subsystem has the authority to use any I/O ports,
it is very easy restrict this authority to the necessary degree.

My experimental kernel consists of more parts:

# trusted public modules
  (this is what I previously called Harmless library)
  Anyone can be given ability to use any "function" from this module
  and we cannot fear that we will raise its authority in any
  unwanted way.

# trusted private modules:
  These encapsulate ability to
  - scribble over the data segment (Video RAM is part of it)
  - read or write to any I/O port
  Subset of this authority is distributed at boot time.

# untrusted powerboxed modules:
  All device drivers should belong to this category. My VGA driver
    is an example of such subsystem.
  All "applications" (if there ever will be any)
    should belong to this category.

# the main program that can see everything. Its purpose is to construct
the subsystems and given them as little authority as they need to be
able to do its job.

For example, the VGA driver constructor (it is called `makeVGA') must be
given four capabilities to functions of proper type:
- the first capability enables it to write the Video RAM
  (a region in the data segment starting at 0xb8000
   that has 4000 bytes)
- the second capability enables it to write the 0x3d4 port
- the third capability enables it to write the 0x3d5 port
- the third capability enables it to read the 0x3d5 port
These capabilities can be easily created via wrapping them in a Pict
*abstraction* (abstractions in Pict are similar to abstractions in the
lambda-calculus, lambda-expressions in LISP or blocks in Smalltalk).
Abstractions in Pict are anonymous processes.

For example, when some part of a system "sees" the `io.write.byte'
capability, it enables it to write arbitrary bytes to arbitrary byte
ports. It can create a new anonymous "function" as follows

	\(value) = (io.write.byte 981 value)

and pass it in a message to that subsystem which needs it (our VGA
driver). Those that are given capability to call this "function" then
will have the authority to write arbitrary bytes to a given I/O number
981 (in hexadecimal system 0x3d5).

I construct VGA driver in a powerbox on page 65.

The VGA driver itself is defined Section 3.1 on page 61

Powerbox in my case means sandbox (the subsystem is not allowed to use
inline C code because that is dangerous; the subsystem is, however,
allowed to use the `Public' module which encapsulates many generally
useful but harmless data-types, functions and processes) which is
selectively enriched with those capabilities that the subsystem needs to
do its job. It follows the good advice given to me in summer
I think.

Because these restrictions are described in a programming language,
there is a wide variety of possibilities how capabilities can be
constrained. If those capabilities were provided by an operating system,
 I am not sure if we had such wide possibilities. In unix, for example,
open file descriptor is some kind of capability. even if we neglect the
fact that these file descriptors cannot be passed around in messages;
there is an "ambient authority" etc etc what we can do is to give it to
a child process. However, we cannot restrict that capability with any
descriptable security policy. In some occasions it might be enough to
let the child process to transfer 10 bytes. The operating system does
not allow such restrictions. Making restrictions of "language-based
capabilities" is trivial because the complete language is at our side in
which we can describe such security policy.

I like this approach even though I see many problems.
- I need to turn hardware interrupts into Pict messages
  (this will require careful reading and understanding the Pict runtime)
- I need to modify the Pict runtime in a way that untrusted subsystems
  will not be able to consume arbitrary amount of free heap of memory
- I need to modify the Pict runtime so that untrusted subsystems
  will not be able to consume arbirary "CPU bandwidth"
Unless those problems are eliminated, Pict will not be practical
alternative. That would be a pity.
Matej Kosik

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: OpenPGP digital signature
Url : http://www.eros-os.org/pipermail/cap-talk/attachments/20070122/fda6b97a/attachment-0001.bin 

More information about the cap-talk mailing list