[cap-talk] More Heresey: ACLs not inherently bad

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Thu Oct 9 05:37:07 CDT 2008


At Thu, 2 Oct 2008 17:09:19 +0000, "Karp, Alan H" <alan.karp at hp.com> wrote:
> The problem is that the compiler needs to exercise rights from two
> sources, the user's rights to read the input file and write the
> output file, and the compiler's right to update the billing file.
> If the compiler uses setuid to run as the user, it can't update
> billing file.  If it runs as itself, it will clobber the billing
> file with the output.

These are false alternatives.  Unix is more powerful, and I am sure
you know how this can be implemented correctly in Unix using file
descriptors.  There are at least three ways:

1. A setuid process can change its effective user ID at any time with
seteuid().  This way, the compiler can run most operations under the
user ID of the caller and only update the billing file with the user
ID of the compiler administrator.

This is well-known and clearly documented all over the place, for
example in the GNU C Library manual "29.8 Enabling and Disabling
Setuid Access", "29.9 Setuid Program Example" and again in "29.10 Tips
for Writing Setuid Programs".

The important thing to note here is that changing the user ID is not a
permanent thing.  The compiler can change back and forth.

2. There is a special function, access(), which checks access to
resources using the real user ID, not the effective user ID.  This can
be used to verify access to the billing file before writing.

3. More secure is to open the billing file under the compiler
administrator user (using seteuid), keep the file descriptor open and
then use setreuid() to drop the compiler administrator privilege.
This is of course closer to the capability model, as the file
descriptor now essentially is the compiler administrator capability.

Alternatively, you can get even closer to the capability model by
dropping the *user* privilege after opening input and output files,
and only run under the file user ID.  This is possible in Linux, but
it's not necessarily possible in every POSIX system.

This demonstrates that Unix systems already make use of ACL and
capability system functionality.

The ACL method using different user IDs can be difficult to get right,
and it has a lot of hair attached to it.  This is particularly true if
you consider multi-threaded applications and various extensions, like
per-thread user IDs.  But, it is there, and it can be used to get
correct behaviour, contrary to what you said.

As for carol's copy service:

> Here's an example I've been using.  Alice wishes to use Bob's backup
> service, which is implemented by using Carol's copy service.
>
>        Alice: bob.backup(foo)
>        Bob:   carol.copy(foo,bar)
>        Carol: copy(a,b) { b.write(a.read()); }
>
> Show me how to do that with setuid without violating least privilege.

As this is an abstract example, it can't provoke more than abstract
interest in me.  There are relatively simple solutions on any Unix
system:

1. Carol's copy service can run with root privileges.  Then it can
assume any user ID, including that of Alice or Bob.

2. As is well known, capabilities can be emulated with an inflation of
ACL IDs: A group carol-and-alice can be used to give Carol access to
Alice's file, and a group carol-and-bob for the mediation of Carol and
Bob.  But, to make this work, you probably also need an inflation of
processes with appropriate setgid and setuid privileges (plus a
supervising master process only accessible to carol) to go along with.

3. Alice and Bob can give file descriptors (== Unix capabilities) to
Carol.  As this is the capability solution and doesn't use setuid, I
consider it cheating in this particular example.

Don't knock the first two options too quickly.  To pull your example
back into the real world: three-way negotiations are very complicated
and tricky business.  Until you go into more detail, I am going to
assume that the negotiations between Alice's, Bob's and Carol's
lawyers and the resulting contracts and business models are going to
cost many times more than a dedicated machine for Carol on which the
copy service is implemented, or a contract between Carol and root for
running the copy service or at least for creation of the necessary
user IDs.

Thanks,
Marcus



More information about the cap-talk mailing list