public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Ulrich Drepper <drepper@redhat.com>, Roland McGrath <roland@redhat.com>
Cc: Glibc hackers <libc-hacker@sources.redhat.com>
Subject: [PATCH] Fix bindresvport
Date: Mon, 21 Nov 2005 20:18:00 -0000	[thread overview]
Message-ID: <20051121201837.GS16723@sunsite.mff.cuni.cz> (raw)

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

             reply	other threads:[~2005-11-21 20:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-21 20:18 Jakub Jelinek [this message]
2005-11-22  4:39 ` Ulrich Drepper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20051121201837.GS16723@sunsite.mff.cuni.cz \
    --to=jakub@redhat.com \
    --cc=drepper@redhat.com \
    --cc=libc-hacker@sources.redhat.com \
    --cc=roland@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).