Re: GPF in tcp_recvmsg in 2.0.32 -- patch attached

Adam D. Bradley (artdodge@cs.bu.edu)
Fri, 5 Dec 1997 03:21:05 -0500 (EST)


Gents,

> > It turns out that there is a nasty problem with cloned processes
> > in that one process (aka thread) can close a socket while another
> > is operating on it. For example, say one thread is blocked in a
> > tcp_recvmsg call, and another thread closes the socket. The first
> > thing that happens is that the kernel panics. The attached patch
> > will fix that problem, but I suspect that it is the wrong
> > solution.
>
> [snip]
>
> The only general short-term fix I've thought of would be to just copy
> the files structure even if CLONE_FILES is specified.

Blech... I'm working on a threaded web server that assumes the current
(normal, POSIX-threads-ish) behavior to easily/inexpensively "migrate"
sockets from the control of one thread to another.

Three possibilities come to mind... (and if all three are bone-headed,
forgive me, it's 3AM here...)

Simple, wrong, kludgy solution: associate a kernel
semaphore/spinlock/whatever-kind-of-mutex with the fd table, if the fd
table is shared then all syscalls involving fd's must acquire it
before proceeding. This is quite obviously bad, because I (and many
others) like having ten threads writing to separate socket fd's
simultaneously.

Icky expensive solution: associate a kernel mutex (whatever kind) with
each fd, if the fd table is shared then all syscalls must acquire the
semaphore before operating on that fd. Problem: Lotsa space, overhead
processing time in _every_ syscall for threaded apps.

Refined version of above, far more feasible: use the traditional
RW-lock mechanism instead; syscalls like open(), close(), and
socket() (anything that modified the table) must get the "write"
permission, while other ops (read(), write()) only need the "read"
permission. Problem: what about select()/poll() with large fd sets?
I suppose it could be assumed that if one of the fd's is write-locked,
then it's a problem in the fd-set (anyone care to correct me on this?)
so an error should be returned (EBADF?). There's also the extra work
to (check whether it needs to) release each read-lock in the fd-set
when returning.

Best solution: write code that doesn't _do_ something like that! ;-)

Corrections, comments, flames?
Adam

--
Things look so bad everywhere      Adam D. Bradley      artdodge@cs.bu.edu
In this whole world what is fair        Boston University Computer Science
We walk blind and we try to see             Ph.D. student and Linux hacker
Falling behind in what could be  ---->  Bring me a Higher Love  ---->  <><