Skip site navigation (1)Skip section navigation (2)
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>