To avoid a kernel panic provoked by a NULL pointer dereference,

do not clear the `sb_sel' member of the sockbuf structure
while invalidating the receive sockbuf in sorflush(), called
from soshutdown().

The panic was reproduceable from user land by attaching a knote
with EVFILT_READ filters to a socket, disabling further reads
from it using shutdown(2), and then closing it.  knote_remove()
was called to remove all knotes from the socket file descriptor
by detaching each using its associated filterops' detach call-
back function, sordetach() in this case, which tried to remove
itself from the invalidated sockbuf's klist (sb_sel.si_note).

PR:	kern/54331
This commit is contained in:
Robert Drehmel 2003-07-17 23:49:10 +00:00
parent 30c2333b1d
commit 4e19fe1081
2 changed files with 8 additions and 1 deletions

View file

@ -1133,8 +1133,14 @@ sorflush(so)
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
bzero(sb, sizeof (*sb));
/*
* Invalidate/clear most of the sockbuf structure, but keep
* its selinfo structure valid.
*/
bzero(&sb->sb_startzero,
sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
splx(s);
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
(*pr->pr_domain->dom_dispose)(asb.sb_mb);
sbrelease(&asb, so);

View file

@ -100,6 +100,7 @@ struct socket {
*/
struct sockbuf {
struct selinfo sb_sel; /* process selecting read/write */
#define sb_startzero sb_mb
struct mbuf *sb_mb; /* the mbuf chain */
u_int sb_cc; /* actual chars in buffer */
u_int sb_hiwat; /* max actual char count */