Subject: file descriptor races
To: None <tech-kern@netbsd.org>
From: Jaromír <jdolecek@netbsd.org>
List: tech-kern
Date: 06/05/2001 12:16:57
Hi,
while merging FreeBSD changes of kern/sys_pipe.c to NetBSD port,
I've discovered there are some file descriptor race protection
changes which would be worth adopting in spirit.

Basically, the issue is like this:
falloc() call is blocking, pipe/socketpair call falloc() two times
to allocate descriptors for the pipe/socketpair. While the second
call is blocked waiting for memory, another thread may come, close
or dup the descriptor and cause Bad Thinks Happen later on.

Though this is not of much issue for NetBSD currently since we
don't have native kernel-backed user threads yet, this might even
be exploitable via e.g. Linux binary using clone(2).

FreeBSD seem to adopt something called fdrop(), which seems to drop
all references to given file. I'd much rather introduce something
like 'atomic falloc'. The proposed interface

int
fallocm(struct proc *p, struct file *resultfp[], int resultfd[], int nelem)

i.e. the function gets passed 'struct file *' array and int array with size
of 'nelem', and would take care to allocate either nelem descriptors, 
or fail and not allocate either (i.e. free those allocated so far, before
it would return to caller). The most simple way to provide 'atomicity'
would be probably to introduce e.g. special FIF_NOTREADY flag,
which sys_dup(), sys_fcntl(), sys_read(), sys_readv(), sys_write(),
sys_writev(), sys_close() would check and return EBADF if it's set.

Or, optionally, we may use FIF_WANTCLOSE | FIF_NOTREADY, and only
change sys_close() to check for FIF_NOTREADY flag (the others
already check the FIF_WANTCLOSE flag).

Opinions?

Jaromir
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
NetBSD - just plain best OS! -=*=- Got spare MCA cards or docs? Hand me them!