Subject: kern/3857: Problem with ephemeral port shortage in in_pcbbind() and in_pcbconnect()
To: None <gnats-bugs@gnats.netbsd.org>
From: None <koji@math.human.nagoya-u.ac.jp>
List: netbsd-bugs
Date: 07/13/1997 14:58:50
>Number: 3857
>Category: kern
>Synopsis: Problem with ephemeral port shortage in in_pcbbind() and in_pcbconnect()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jul 13 04:20:02 1997
>Last-Modified:
>Originator: Koji Imada - je4owb/2
>Organization:
Mathematics Group of Graduate School of Human
Infomatics, Nagoya University, Japan.
>Release: 970705
>Environment:
System: NetBSD bimota 1.2G NetBSD 1.2G (BIMOTA) #: Wed Jul 2 01:36:36 JST 1997 koji@ducati:/mnt2/NetBSD/work/src-ufs-mod/sys/arch/i386/compile/BIMOTA i386
>Description:
Current in_pcbbind() returns EAGAIN if ephemeral port is not
available. But in_pcbbind() set inp->inp_laddr when nam != 0.
Because of non-null inp->inp_laddr when in_pcbbind() returns
EAGAIN, subsequent in_pcbbind() call never succeeds.
And in_pcbconnect() doesn't assumes failure of in_pcbbind()
with null argument. This could cause binding local port 0.
>How-To-Repeat:
If all ephemeral port are exhausted, in_pcbconnect() will bind
local port 0 and in_pcbbind() with 0 port and non-null address
will return EAGAIN and subsequent call will never succeeds.
>Fix:
Apply following patch.
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netinet/in_pcb.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 in_pcb.c
--- in_pcb.c 1997/04/01 07:17:18 1.1.1.2
+++ in_pcb.c 1997/07/13 05:38:37
@@ -184,6 +184,8 @@
if (!in_pcblookup_port(table, inp->inp_laddr,
htons(lport), wild))
goto found;
+ if (!in_nullhost(inp->inp_laddr))
+ inp->inp_laddr = INADDR_ANY;
return (EAGAIN);
found:
table->inpt_lastport = lport;
@@ -314,9 +316,11 @@
inp->inp_lport) != 0)
return (EADDRINUSE);
if (in_nullhost(inp->inp_laddr)) {
- if (inp->inp_lport == 0)
- (void)in_pcbbind(inp, (struct mbuf *)0,
- (struct proc *)0);
+ /* now in_pcbbind() may return EAGAIN... */
+ if (inp->inp_lport == 0 &&
+ in_pcbbind(inp, (struct mbuf *)0,
+ (struct proc *)0) == EAGAIN)
+ return (EAGAIN);
inp->inp_laddr = ifaddr->sin_addr;
}
inp->inp_faddr = sin->sin_addr;
>Audit-Trail:
>Unformatted: