[net.bugs.4bsd] Panic in soqremque from sonewconn

arwhite@watmath.UUCP (Alex White) (02/17/84)

Subject: in_pcbdetach does a sofree
Index:	/sys/netinet/in_pcb.c 4.2BSD

Description:
	System dies with a panic from a garbage pointer in soqremque called
	from sonewconn.
	What happens is that sonewconn, calls tcp_usrreq which calls
	tcp_attach, this calls in_pcballoc which succeeds, but then
	tcp_newtcpcb fails due to lack of mbufs.  tcp_attach hence
	calls in_pcbdetach to clean up.  in_pcbdetach unfortunately
	invokes sofree which releases the socket itself.  we then
	return back up to sonewconn.  Sonewconn now tries to clean up
	and release the socket itself; it calls soqremq with the socket
	which now has a zero pointer for so_head and craps out.
	Superficial examination of code as in udp_usrreq, PRU_ABORT
	shows that it invokes in_pcbdetach and then itself calls sofree
	which was done in in_pcbdetach!
Repeat-By:
	Run out of mbuf's.  If you don't crash of panic: exit: m_getclr
	first (I have a fix for that one...) I suppose its probable
	that you'll hit this after a while...
	How to run out of mbuf's is another bug, which I haven't tracked
	down yet - but I suspect that it has something to do with
	unix domain ipc being done by students....

thomson@uthub.UUCP (Brian Thomson) (02/20/84)

You run out of mbufs because someone is using UNIX domain datagrams,
which are chock full o' bugs.  In this case, it is a misuse of
the sbappendaddr() routine that causes the trouble.

I have a list of 5 bugs in that stuff, and fixes for all of them.
If there is sufficient interest I will post my uipc_usrreq.c, but
there is always the possibility that Berkeley will eventually do it
with different semantics.

I would recommend that all 4.2BSD sites either fix this stuff or disable
it.  Otherwise you run the risk of panics, lost mbufs, orphaned file
descriptors, and improper reference counts when some curious user at
your site tries it out.  Disabling is easy.  In sys/uipc_usrreq.c,
routine unp_usrreq(), change the switch case:

	case PRU_ATTACH:
		if (unp) {
			error = EISCONN;
			break;
		}
		error = unp_attach(so);
		break;

to be:

	case PRU_ATTACH:
		if (unp) {
			error = EISCONN;
			break;
		} else if (so->so_type == SOCK_DGRAM) {
			/* Disabled because of a buggy implementation */
			error = ESOCKTNOSUPPORT;
			break;
		}
		error = unp_attach(so);
		break;


-- 
			Brian Thomson,	    CSRG Univ. of Toronto
			{linus,ihnp4,uw-beaver,floyd,utzoo}!utcsrgv!thomson