Subject: symlink-to-dir-race-free unlink/rmdir
To: None <tech-security@netbsd.org, tech-kern@netbsd.org>
From: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
List: tech-security
Date: 03/07/1999 15:10:46
So, while I was reading through namei in the process of implementing
sys___getcwd, i realized that there's a trivial way to implement
symlink-safe variants of the unlink() and rmdir() syscalls.  (I'm
proposing that they should be called __sunlink() and __srmdir().
Anyone have any better ideas for what to call them?)

The user-space rm and rmdir commands would get new arguments to use
them instead of unlink, naturally.

The nameidata struct passed to namei() contains an ni_loopcount field,
which on return contains the number of symlinks traversed in the
course of resolving this directory.  If, on return from namei(), this
field is non-zero, the new syscalls would fail with ELOOP..  

This check could also be done by adding a new namei flag,
NOCROSSLINK, which is akin to NOCROSSMOUNT, and having the new system
calls set this flag.  

A more radical approach would be to provide variants of the usual
pathname-taking system calls which take a flags parameter which let
the caller set (among other things) the NOCROSSMOUNT, FOLLOW/NOFOLLOW,
REQUIREDIR, and the proposed NOCROSSLINK flag.  I don't think we want
to go there for 1.4.

				- Bill