One place where one would like efficient revocation of a capability is when a capability to a mutable array is passed to a routine. It would be nice if it were not necessary to trust the routine not to retain the reference and use it subsequent to returning from the current call perhaps to fetch data that was subsequently added to the array, or to modify the array after the return. Of course sometimes the original purpose of the call is to allow just this, but more often it would be better if the caller were able to conveniently and efficiently revoke access upon return. (Keykos can do this inefficiently when the array is a segment. Java arrays cannot be indirected polymorphically, however.)
Looking more closely at the case of the mutable array shows two patterns. Often all that is needed by the routine is an array state and passing the array reference is merely a cheap way to do this. Some languages allow passing a reference by which the array cannot be modified and combine efficiency security. C and C++ allows a parameter type int * const which would do the trick except for C’s lack of type safety. I think that Java’s final can not be used in this way to define a such a weakened parameter reference. Keykos does this polymorphically with the somewhat heavy indirect segment node.
Another pattern is when the routine’s purpose is to modify the array. In that case the underlying need is to pass an array state and receive another in return. Often the changes are few and it is exceedingly efficient to change the array in place. The Keykos caller can create a segment node that provides RW access to the array and delete the node afterwards.
Arrays are not the only mutable objects references which are passed to untrusted routines. A software defined (callable) mutable object in place of the array presents exactly the same set of patterns. It is generally possible to wrap callable objects polymorphically and filter methods that would modify the object if desired. Designing such a filter may require more knowledge of the wrapped object than the caller may otherwise be expected to require. Some mutable objects will include a method to yield read only access to itself.
Both the patterns above where the routine’s need for access is temporary may be often solved in Keykos by creating an instance of the routine as a confined object and deleting the object after the return and before other access to the object is allowed. This works for arrays and callable objects. A lighter version of this is creating a confined object with a kept meter. The meter can be turned off while the routine should not be accessing the object. This can be highly efficient as it does not include the overhead of creating and destroying the routine instance. It also allows mutable state in the routine. A variant on this is to grant adjustable access to the segment via a segment node. Access is adjusted with the segment service key. The meter solution may avoid the kernel overhead of modifying the memory map.
Other solutions to this problem may be by way of linear logic which insures that some reference types may be passed but not duplicated. The routine must return the reference thereby proving that it no longer holds it. I don’t know how efficiently this can be implemented but it seems possibly very efficient. I think it could be a statically checked type in a type safe language. It would be nice if the semantics were to pass and return array states while the implementation passed a reference.