Slogan: Don’t separate names from authority.
The confused deputy is the best parable I know describing the pitfalls of separating authority from names.

In Java a called routine can access data, access to which is passed as a reference. The argument provides the routine with the authority to access the data along with the identity of the data. Java is unusual in that this rule is actually enforced, in contrast to C where the routine can fabricate authority to any data. It is just this pattern of bundling naming with authority that the OS should conform to in

Not only is conventional OS naming bad security, it performs poorly. From the perspective of capability design, systems with separate naming and authority mechanisms suffer a manifest performance problem. The following pattern is repeated in each of the several name spaces that the Unix kernel supports:

Note the two mechanisms. The permission mechanism may have a large cost if a search is necessary to find a match that allows access. By contrast capability mechanisms establish authority immediately upon resolving the meaning of the name. In addition the data that compose the name are in a form convenient to kernel code instead of convenient to a person. This means that long path names for files are not required for most file accesses. In KeyKos for recently used capabilities which are in RAM, only a few instructions are needed to find the real address of the designated object.

The categorical nature of these conventional access rules means that authority must be granted in large hunks (categorically), rather than with the narrow authority that a capability can grant. There is often no way to know to whom you are granting authority when you make a file accessible to everyone in a group.

Another consequence of classic design is that objects are implicitly owned by some task, thread, user or other agency. Objects may not normally be transferred from one agency to another. This situation is often cited as a sign of good security. But why, if I have opened a file, should I be unable to pass that opened file to you so that you can proceed from where I have left the file cursor. If I can pass the data to you, or write what you tell me into the file, what problems are solved by my being unable to pass the open file to you?

In Unix, access to a file descriptor is passed to a newly created fork in Unix just in case a bit is on in a flags word passed upon opening the file. This makes arguing about who has access to what difficult. Such ad hoc access mechanisms seem to be distributed throughout Unix. The real flaw is that UNIX lacks a uniform resource interface, and therefore has a different way of doing this for each resource. (Thanks to Jonathan Shapiro for correcting my understanding of Unix here.)

I have complained enough about Unix here. Let me complain about IBM’s CMS which runs in their VM operating system. Each file operation such as read or write provides the file name instead of some file descriptor as in Unix. As in Unix the system is charged with remembering where within a file, the program has progressed to. The system creates a file cursor for each unique pair of program and file. As a result a file compare program is unable to compare a file with itself since that requires two instances of the cursor. Such a task arises while debugging the compare program or when the compare program is called by a program whose natural logic does not preclude invoking the compare when the operands are the same.

In this case Unix logic works better by using the file descriptor in each read operation which effectively names the cursor by naming the file descriptor. In this regard the Unix file descriptor is like a capability. Unfortunately it cannot be passed between Unix processes in most Unix implementations.