Date: Mon, 30 Jul 2001 16:20:54 -0700 (PDT) From: Richard Andrades <richard@xebeo.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/29336: non-privileged user opening routing socket causes resource leak Message-ID: <200107302320.f6UNKsu93862@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 29336 >Category: kern >Synopsis: non-privileged user opening routing socket causes resource leak >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jul 30 16:30:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Richard Andrades >Release: RELENG_4_1_1_RELEASE (Revision 1.1.2.2) >Organization: Xebeo Communications, Inc. >Environment: FreeBSD X2.xebeo.com 4.1.1 FreeBSD 4.1.1 #11: Tue Jul 17 14:47:29 EDT 2001 richard@X2.xebeo.com:/net/scratch/richard/kern/kernel/sys/compile/GENERIC i386 >Description: If a routing socket is opened without root permissions, the socket() call fails. But the kernel fails to free the socket structure which it already allocated at the begining of the system call. This causes a resource leak in the socket table. If this happens often enough, the system runs out of socket descriptors and is unable to start any new network operations. >How-To-Repeat: Run: --------------------------------------- main() { for(;;) socket(AF_ROUTE, SOCK_RAW, 0); } --------------------------------------- as a non-root user. >Fix: Note: I checked the latest version and this bug has not yet been fixed. FILE: src/sys/net/rtsock.c Function: rts_attach() ---Begin code fragment---------------------------------------- MALLOC(rp, struct rawcb *, sizeof *rp, M_PCB, M_WAITOK); /* XXX */ if (rp == 0) return ENOBUFS; bzero(rp, sizeof *rp); /* * The splnet() is necessary to block protocols from sending * error notifications (like RTM_REDIRECT or RTM_LOSING) while * this PCB is extant but incompletely initialized. * Probably we should try to do more of this work beforehand and * eliminate the spl. */ s = splnet(); so->so_pcb = (caddr_t)rp; error = raw_usrreqs.pru_attach(so, proto, p); /* NOTE: Will return error if not root */ rp = sotorawcb(so); if (error) { /* Begin BUG FIX */ so->so_pcb = 0; /* Otherwise the socket won't be freed */ /* End BUG FIX */ splx(s); free(rp, M_PCB); return error; } ---End code fragment------------------------------------------------ Explanation: ************ In the function socreate() in the file src/sys/kern/uipc_socket.c there is the following code fragment: ----------------------------- error = (*prp->pr_usrreqs->pru_attach)(so, proto, p); /* NOTE: This goes to rts_attach() */ if (error) { so->so_state |= SS_NOFDREF; sofree(so); return (error); } ------------------------------------ Looking at the function sofree() in the same file, we find: ------------------------------------- void sofree(so) register struct socket *so; { struct socket *head = so->so_head; if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) return; ----------------------------------- So if rts_attach() fails to reset the so_pcb member, sofree() will not free the socket. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107302320.f6UNKsu93862>