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>
