From owner-freebsd-bugs Mon Jul 30 16:30: 9 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id E337137B403 for ; Mon, 30 Jul 2001 16:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id f6UNU1K94722; Mon, 30 Jul 2001 16:30:01 -0700 (PDT) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 2905837B401 for ; Mon, 30 Jul 2001 16:20:54 -0700 (PDT) (envelope-from nobody@FreeBSD.org) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id f6UNKsu93862; Mon, 30 Jul 2001 16:20:54 -0700 (PDT) (envelope-from nobody) Message-Id: <200107302320.f6UNKsu93862@freefall.freebsd.org> Date: Mon, 30 Jul 2001 16:20:54 -0700 (PDT) From: Richard Andrades To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: kern/29336: non-privileged user opening routing socket causes resource leak Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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