Access Control
- Access Control Lists
- Capabilities
TOCTTOU
- unfortunately, for all our effort on concurrency,
some things just aren't solvable in the Unix API.
- various system calls take names, but the file it refers to
can change between each call, making it difficult to know
what you're really doing
- traditionally this problem has come up in privileged code,
which needs to perform some checks on a file, and if the
checks succeed, do something to that file. if the file
name points to a different inode between the "check" and
the "do", we have a security problem.
- called "time-of-check to time-of-use" (TOCTTOU) bug.
- usual example: cleaner for a /tmp directory
- root runs: rm /tmp/*/*
(really something like
find /tmp -not-accessed-recently | xargs rm)
- two phases: expand list of files, then unlink them
- attacker: mkdir /tmp/a; echo >/tmp/a/passwd
- root's rm: finds /tmp/a/passwd
- attacker: rm /tmp/a/passwd; rmdir /tmp/a;
ln -s /etc /tmp/d
- root's rm: unlink("/tmp/a/passwd"),
unlinks passwd from /tmp/a==/etc
- what's the fix? expose more inodes (as file descriptors)
to avoid duplicate namei() calls that might return different
values.
- fstat allows us to check file status for an inode,
rather than path (real unix also has stat, which
can lead to trouble)
- how to do a directory lookup on a directory inode?
- how to execute a file with a particular inode?
In early versions of Unix there was no mkdir() system call. here's
the source for /bin/mkdir (from v7 unix):
if ((mknod(d, 040777, 0)) < 0) {
fprintf(stderr,"mkdir: cannot make directory %s\n", d);
++Errors;
return;
}
chown(d, getuid(), getgid());
mkdir was setuid to root -- it ran as root even if started by
an ordinary user, since mknod() is a privileged call.
what's the problem?
how to exploit it?
cd /tmp
mkdir foo & ./exploit
exploit waits for foo to appear, then removes it,
substitutes a link to e.g. /etc/passwd
unix used to be full of such bugs. e.g. mail delivery command
appended to /usr/spool/mail/cs123456, running as root:
stat(/usr/spool/mail/cs123456)
if owned by cs123456
open and write
how do people fix tocttou bugs?
atomic mkdir() call
f-calls:
fd = open(file)
fstat(fd)
if(ok)
fchown(fd)
don't run as root: structure s/w to drop privileges when possible
e.g. setuid(cs123456) before delivering mail
rest of course
- will talk about a research paper per lecture
- lecture after next lecture: paper on getting both crash-consistency and
performance in a file system.
- read paper before class, lecture will discuss it in detail,
be prepared.