Separate address spaces and vault security

Greg Lindahl, March 20 1997

Separate address spaces

Legion objects, according to the formal specification, run in separate address spaces, and this is very important for Legion security. The current implementation of the host object (0.0) runs all Legion objects using the same UID; they can use the debugger interface to read each other's address spaces. Thus, the existing implementation Legion system is vulnerable to attack from anyone who can run an object.

There is a way to get around this. The normal setuid-type system calls are not useful, because only root can fully get rid of one UID and adopt another. And we want to avoid root if at all possible.

We can get separate UID's by have a series of accounts with different UID's and a special program as the login shell. This program is actually a Legion Object ("ExecObject") whose purpose in life is to do nothing but exec things when commanded by the HostObject. The StartupObject only allows one object to run at a time using its UID, and also makes sure that it is only running once. Normal Legion security and authentication stuff are used.

These special accounts can either have no password, in which case anyone could start all of them, or they could have a password which the HostObject knows. These accounts can't be used to break in in any case; the only issue is that they could be used for a denial of service attack, by chewing up lots of swap space.

This scheme avoids root access, but does require creating accounts. This is probably acceptable to almost all sites, and is in line with our other security trade-offs. A site would need to give up thousands of accounts in order to run a full-blown Legion system. If they have a local limit of 64k UID's, this might be a problem, but most OSes are moving towards 32-bit UID's (e.g. Solaris 2.6 should have them.)

Unfortunately, we are still at risk to random Legion user objects creating setuid programs in /legion_tmp or any other place which they are capable of writing to on the host. If the areas where Legion objects are capable of writing are non-setuid enabled (most OSes have this feature), we are OK. The risk comes from the fact that an attacker could run a series of objects to create a series of setuid shells with different UID's on a host. Then they can go back later and attack new objects reusing these same UID's.

I believe that NT can support similar functionality. I have heard of configuration tools which leave an administrator process running on all PC's so they could be upgraded at any time over the network. We could probably start all of these processes at boot time. I'm not sure if it would be possible to restart them later if they died without a reboot. Creating thousands of accounts at once under NT is a pain in the neck, but that's not our fault. The UID space is large enough that there's no problem with running out of them.

Vault security

Adam's recent draft tech report describes object activation and deactivation in some detail. In the Unix vault implementation, an OPR (object persistent representation) is a collection of files/subdirs in a directory. Access to these files is via the LegionBuffer object interface, not directly though the Vault object. So we must use Unix file permissions to secure these files. This interacts with the UID issue, which is why this section is in with the separate UID discussion.

In order to get some security-through-obscurity, these directories can be stored in a directory with mode ugo-r, and have random names. So an attacker could only read these files if they can guess the (random) name of the directory. If the object's access is via NFS, this is easy through snooping on the network, but if the access is via local disk, this is hard. So, this security is cheap, reasonably effective, and works even if all objects run with the same UID. But some admins have installed "lsof" setuid, which allows any user to get a list of files so we will never know if this

If we wanted to do a good job at security, we would need to arrange that the files can be read and written by both the object and the vault, but no one else. If objects run with different UID's, we can do this using an ACL on the file, which is only supported on some Unix versions. There is no clever way to do this with weird groups. If you tried making a hard link to the file and having the 2 names have different owners, that's difficult because non-root processes can't chown files from one UID to another (although sysv used to have this "feature".) So, I believe that there is no clever way to get this right on Unix sans ACLs, but I am open to suggestions.

Under NT we can put an ACL on the directory to allow both the vault and the current UID of the object to access the files, and no one else. I hope that if the vault is the real owner of the directory it will be able to manipulate the ACL to remove the object's rights when the object is inactivated, but I am not that familar with NT ACLs.

Solaris also has ACL's, but Linux does not. It isn't 100% clear to me from reading the manpage that it is possible to create an ACL which allows 2 UID's to read a file, and no one else, but that capability should be there and the documentation is probably unclear.