two kernel socket bugs and fixes

Mike Cherepov cher at ksr.com
Fri Mar 2 02:44:09 AEST 1990


Two bugs having to do with rights-passing and file structure garbage
collection in kernel socket code:

making a sendmsg() call with huge msg_accrightslen and msg_accrights
crashes our Solbourne. The problem is that the kernel sendit() does not
check whether the rights (int array in AF_UN*X domain) fit into an mbuf.
Something like this before the sockargs(&rights,...)  call in sendit()
should help:

	        if (mp->msg_accrightslen > MLLEN) {
                u.u_error=EMSGSIZE;
                return;
        }

A more interesting case (crashes a SparcStation) involves passing rights
to a socket, closing it, then opening and closing another socket causing
unp_gc (the garbage collection) to come alive:

	get datagram socket in AF_UN*X domain, assume fd is 3;
	bind it;
	int rights[2]={3,3};
	call sendmsg(3,msg,0) passing rights to itself;
	close(3);
	get another socket;
	close it, and presto - machine crashes

This is how we seem to get there:
unp_gc 			/* garbage collection */
unp_discard 		
closef 
soo_close 
soclose 		/* NOFDREF flag on the orphaned socket cleared here */
sofree
sorflush 		/* flush rights buffers */
unp_dispose 
unp_scan 
unp_discard
closef			/* close same fd we are working on */
soo_close
soclose			/* but NOFDREF cleared already */
panic


One way to fix this is to make sure we don't call closef on the same file
the second time around, to this end unp_discard could do this:

        if (fp->f_msgcount<=0)
                return;

before doing anything else. Discard is not supposed to be called if there
are no rights to discard. However, I am not sure it does not introduce
some other unforeseen problems; perhaps looking at NOFDREF is a better way
to go. Any comments from well-informed quarters?

		Mike Cherepov
			expressing views not necessarily coincidental
			with those of my employer...
		uunet!ksr!cher
		ksr!cher at harvard.harvard.edu



More information about the Comp.sys.sun mailing list