www.eros-os.org/essays/capintro.html
EROS, which is currently the fastest capability system in existence, does this in system software, and the data suggests that there wouldn't be any real benefit to doing it in hardware. Capability-Based Computer Systems In a capability-based computer system, all access to objects is done through capabilities, and capabilities provide the only means of accessing objects. In such a system, every program holds a set of capabilities. If program A holds a capability to talk to program B, then the two programs can grant capabilities to each other. In most capability systems, a program can hold an infinite number of capabilities. A better design allows each program to hold a fixed (and small -- like 16 or 32) number of capabilities, and provides a means for storing additional capabilities if they are needed. The only way to obtain capabilities is to have them granted to you as a result of some communication. Holding a large number of capabilities is usually foolish. The goal is to make the set of capabilities held by each program as specific and as small as possible, because a program cannot abuse authority it does not have. In this kind of system, a program that wants to perform an operation on an object must hold a capability to that object. To perform the action, it invokes the capability and names the action that is to be performed. In the UNIX operating system, for example, the system call read(fd, buf, sz) system call can be thought of as performing the read operation on the file named by fd (the capability), passing the arguments buf and sz. Aside from the fact that UNIX file descriptors carry some associated information about the current file offset, a UNIX file descriptor is essentially a capability. Writing Things Down The main problem with capabilities is finding a way to save them to disk so that you can get them back. This is one of the main reasons that few capability systems have been built, and the main reason why most current capability systems break down at the file system boundary. Assume for a minute that your program had a capability that let it create a file and write things down in it. Suppose it does so, and all of the information you need has now been written down. My helpful dog, Sheena, now comes along and kicks your computer's plug out of the wall. We start the system up and we now have to answer a chicken and egg problem: * To access the file, you must first have a capability to the file system. Where do the first few programs get their capabilities from? These problems basically stumped capability system designers until the early 1970's. Conventional Solution: Access Control Lists The usual solution has been to have some kind of file system, grant every program the right to use the file system, and use some sort of user-identity based system to decide which programs can open which files. If a program is running on behalf of Natasha (my other dog), it can open any of the files that Natasha created. Such a system is called an access control list (ACL) system. Every object has attached to it a list of users and the actions that each user is authorized to perform. If the user is on the access control list, then programs operating on behalf of that user can obtain a capability for that object. Once they have the capability, they can manipulate the object itself. Take a minute to go back and look at the four things an access control mechanism was supposed to accomplish. ACL systems can prevent and revoke access, but they can neither limit access nor grant access. All programs running on behalf of Natasha -- even that raging inferno program written by a stranger in Norway -- can get access to any of Natasha's objects. In current ACL systems, there is no means to subset these rights. Also, there is no way for Natasha to delegate some of her authority (say, access to a single file she does not own) to me unless Natasha owns the object in question. Unless she owns the object, she cannot modify the access control list. A Better Solution: Universal Persistence A better solution is not to have a common file system, and not to give any program access to the file system by default. File systems are very useful, but most programs and subsystems do not need access to them. A spell checker that runs as part of a word processor, for example, needs access to the particular files it works on, but has no need to open any other files (and therefore no need of access to a file system). If things aren't remembered by writing them in a file, some other means must be found to remember them. Every five minutes, write down all of the things the computer is working on. If Sheena pulls the plug, the system simply comes back to the last saved copy. Since the saved copy includes all of the running programs, there is no need to figure out who is entitled to what when the system restarts. In practice it's actually faster than file systems and requires less code. Of course, the user may have walked away from the machine, so a means is needed to get back to their work. The solution is to give every user a program that runs on their behalf (the window system, if you like) at all times. The job of the login agent is to reconnect you to your window system, where all of your programs are still running.
You Can't Get There From Here Traditional access control systems run into trouble with a variety of important problems. Here are some examples of these problems in today's computersystems, and an explanation of why the problems do not exist in capabilitysystems. Privileged Programs Consider the program that changes your password. It needs the authority to read and write the password file, but must not give that authority to you. In an ACL system the only way to do this is to have access to the password file restricted to a special user (root or sysadm), and have some means to say that the password program runs as that user. This has led to ideas suchas the setuid bit (lets a program runs as both the owner usually root and as you at the same time) or the system privilege table (VMS: lists programs with special privileges in a system-wide table). Giving the password program all of root's authority is simply too much. In the VMS mechanism, the program file itself can be attacked, leaving a hard to find security hole. The next timethe program is run it will obey the new program, which can do absolutely anything. Maybe more important, such programs tend to get into trouble over time. As maintainers alter these programs without fully understanding their constraints, they become sources of new security flaws. The right solution is to explicitly give the program access to the passwordfile, and not leave the password program lying around in a file system where it can be overwritten. In a capability system, you simply give the program a capability to the password database and let it run forever. You then give out a capability that lets people run the password program but does notlet them read or modify that program. Access Restriction Suppose you have a program that manages your financial data. You don't really want it sending that information to the IRS without your permission, butyour computer is attached to the network. In an ACL system, since you haveaccess to the network, so does the program. In a capability system you simply leave the capabilities for the network out when you install the program, guaranteeing that it cannot send data to those helpful, friendly people at the IRS. You may have noticed that people keep finding new security problems with Java. It is better to have done the job right inthe first place. Capabilities have a formal, mathematically sound model that can be (and has been) used to prove their security. Collaboration The really hard part, however, is dealing with collaboration. I'm afraid to give out the binarycode, because somebody will decompile it and steal my program (yes, this really does happen). You have some very secret data concerning the results of a new drug trial. You need to run my program, but you're not willing to show me the data. In a capability system, we can set things up so that you can run the program without being ...
|