public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix bindresvport
@ 2005-11-21 20:18 Jakub Jelinek
  2005-11-22  4:39 ` Ulrich Drepper
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2005-11-21 20:18 UTC (permalink / raw)
  To: Ulrich Drepper, Roland McGrath; +Cc: Glibc hackers

Hi!

Unless the caller of bindresvport is lucky, the first bindresvport that
sees all STARTPORT .. ENDPORT ports (i.e. 600 .. 1023) used will fail.
While subsequent bindresvport calls would probably succeed again
(as 512 .. 1023 range would be scanned next time), most programs bail
out on the first failure.
The reason why the bindresvport call that changes startport variable
usually fails is that unless port ends with a value
> (ENDPORT - (STARTPORT - LOWPORT)) == 935, after jumping to again
label it will try all ports in the range portN .. portN+87
(where portN is value of port variable on the startport = LOWPORT;
statement), but those usually have been already checked previously
to be already bound.
The fix can be either to set nports not to STARTPORT - LOWPORT,
but ENDPORT - LOWPORT + 1 (guess solution shortest for code size,
but might scan up to 423 ports unnecessarily again), or
startport = LOWPORT:
nports = STARTPORT - 1;
port = LOWPORT;
(the disadvantage would be that in case of overflowing the 600 .. 1023
area it would always start with port 512), or as done in the patch below,
setting port to something in between LOWPORT and STARTPORT - 1 and making
sure that wrapping in that loop will be when port >= STARTPORT.

2005-11-21  Jakub Jelinek  <jakub@redhat.com>

	* sunrpc/bindrsvprt.c (bindresvport): Wrap around to startport
	in the loop if port is bigger than endport, initially set to
	ENDPORT.  When changing startport, set endport and port
	appropriately.

--- libc/sunrpc/bindrsvprt.c	23 May 2005 19:03:43 -0000	1.11
+++ libc/sunrpc/bindrsvprt.c	21 Nov 2005 19:52:27 -0000
@@ -74,14 +74,13 @@ bindresvport (int sd, struct sockaddr_in
   int res = -1;
 
   int nports = ENDPORT - startport + 1;
+  int endport = ENDPORT;
  again:
   for (i = 0; i < nports; ++i)
     {
       sin->sin_port = htons (port++);
-      if (port > ENDPORT)
-	{
-	  port = startport;
-	}
+      if (port > endport)
+	port = startport;
       res = __bind (sd, sin, sizeof (struct sockaddr_in));
       if (res >= 0 || errno != EADDRINUSE)
 	break;
@@ -90,7 +89,9 @@ bindresvport (int sd, struct sockaddr_in
   if (i == nports && startport != LOWPORT)
     {
       startport = LOWPORT;
+      endport = STARTPORT - 1;
       nports = STARTPORT - LOWPORT;
+      port = LOWPORT + port % (STARTPORT - LOWPORT);
       goto again;
     }
 

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix bindresvport
  2005-11-21 20:18 [PATCH] Fix bindresvport Jakub Jelinek
@ 2005-11-22  4:39 ` Ulrich Drepper
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Drepper @ 2005-11-22  4:39 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Roland McGrath, Glibc hackers

Applied.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-11-22  4:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-21 20:18 [PATCH] Fix bindresvport Jakub Jelinek
2005-11-22  4:39 ` Ulrich Drepper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).