Date: Mon, 12 Mar 2001 23:14:33 +0200 (EET) From: unicorn@Forest.Od.UA To: FreeBSD-gnats-submit@freebsd.org Subject: kern/25751: Patch against crash caused by operations with half-binded sockets. Message-ID: <200103122114.f2CLEX901306@Unicorn.Forest.Od.UA>
next in thread | raw e-mail | index | archive | help
>Number: 25751 >Category: kern >Synopsis: Patch against crash caused by operations with half-binded sockets. >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Mar 12 13:20:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Winged Unicorn >Release: FreeBSD 5.0-CURRENT i386 >Organization: Valhala >Environment: System: FreeBSD Unicorn.Forest.Od.UA 5.0-CURRENT FreeBSD 5.0-CURRENT #0: Wed Feb 21 20:56:33 EET 2001 root@Unicorn.Forest.Od.UA:/usr/src/sys/compile/FOREST i386 Working jail environment with NIS/YP installed. >Description: If bind() call fails to allocate port due `prison_ip' permission failure, socket left in half-binded state (bind returns an error, but doesn't undo socket state (in case of failure bind should left inp_laddr.s_addr == INADDR_ANY && inp_lport == 0, indicating, that socket is NOT yet binded)). In upper case `bind' aborted, left in binded state, but doesn't inserted in hashlists (in_pcbinshash). Any operations with such sockets will cause dereferencing of hash pointers and lead to crash. >How-To-Repeat: In jail with NIS/YP environment type `id some_nis_user'. >Fix: `cvs diff -u in_pcb.c' follows: Index: in_pcb.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.81 diff -u -r1.81 in_pcb.c --- in_pcb.c 2001/03/04 21:28:40 1.81 +++ in_pcb.c 2001/03/12 10:39:56 @@ -272,8 +272,15 @@ int count; if (inp->inp_laddr.s_addr != INADDR_ANY) - if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr )) + if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr )) { + /* + * Undo any address bind that may have + * occurred above. + */ + inp->inp_laddr.s_addr = INADDR_ANY; + return (EINVAL); + } inp->inp_flags |= INP_ANONPORT; if (inp->inp_flags & INP_HIGHPORT) { @@ -281,8 +288,14 @@ last = ipport_hilastauto; lastport = &pcbinfo->lasthi; } else if (inp->inp_flags & INP_LOWPORT) { - if (p && (error = suser_xxx(0, p, PRISON_ROOT))) + if (p && (error = suser_xxx(0, p, PRISON_ROOT))) { + /* + * Undo any address bind that may have + * occurred above. + */ + inp->inp_laddr.s_addr = INADDR_ANY; return error; + } first = ipport_lowfirstauto; /* 1023 */ last = ipport_lowlastauto; /* 600 */ lastport = &pcbinfo->lastlow; @@ -306,10 +319,6 @@ do { if (count-- < 0) { /* completely used? */ - /* - * Undo any address bind that may have - * occurred above. - */ inp->inp_laddr.s_addr = INADDR_ANY; return (EADDRNOTAVAIL); } @@ -343,8 +352,13 @@ } } inp->inp_lport = lport; - if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr)) - return(EINVAL); + + if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr)) { + inp->inp_laddr.s_addr = INADDR_ANY; + inp->inp_lport = 0; + return (EINVAL); + } + if (in_pcbinshash(inp) != 0) { inp->inp_laddr.s_addr = INADDR_ANY; inp->inp_lport = 0; >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?200103122114.f2CLEX901306>