Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 78295

Summary: rresvport wraps socket number
Product: [Retired] Red Hat Linux Reporter: Ben Woodard <woodard>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED CURRENTRELEASE QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.3CC: drepper, fweimer, mitr, roland
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Fixed In Version: 2.3.2-27.9 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2003-04-22 07:39:33 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Ben Woodard 2002-11-20 21:04:24 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20021003

Description of problem:
When all the reserved ports below 512 are already in use and you pass a
suggested port number below 512 to rresvport then rresvport will assign you a
non-reserved port. 

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1.write a program that calls rresvport 513 times with a parameter less than 512

Actual Results:  a non reserved port

Expected Results:  -1 & errno set to EAGAIN

Additional info:

Comment 1 Ben Woodard 2002-11-20 21:10:24 UTC
The bug is easy to see in rresvport:

In glibc/inet/rcmd.c in the function rresvport_af:

   454          for (;;) {
   455                  *sport = htons((uint16_t) *alport);
   456                  if (bind(s, (struct sockaddr *)&ss, len) >= 0)
   457                          return s;
   458                  if (errno != EADDRINUSE) {
   459                          (void)__close(s);
   460                          return -1;
   461                  }
   462                  (*alport)--;
   463                  if (*alport == IPPORT_RESERVED/2)
   464                          break;
   465          }

In line 463 you can see that if you pass a port number < IPPORT_RESERVED/2 into
the function the loop doesn't terminate and *alport can become less than 0 in
which case a non reserved port is assigned.

An appropriate fix may be something like:

if (*alport == IPPORT_RESERVED/2 || *alport < 0 )

Comment 2 Jakub Jelinek 2003-02-19 17:59:37 UTC
E.g. documents that the caller
must pass an argument between 512 and 1023 inclusive.
Don't know if it wouldn't be better to add if (*alport < IPPORT_RESERVED / 2 || *alport >= IPPORT_RESERVED) { errno = EINVAL; return -1; }
early in the function (and change (*alport)--; if (*alport == IPPORT_RESERVED/2)
to if ((*alport--) == IPPORT_RESERVED / 2) so that a) it is possible to call
rresvport with *alpost == 512 and it tries even port 512.

Comment 3 Roland McGrath 2003-02-19 18:57:39 UTC
Traditional BSD behavior (rresvport is a 4.2BSD invention) tries the given port
value and if that exact port is not available it ignores it and selects without
regard to the original value.  Hence some traditional callers might not even
initialize the value.  Such uses might already be broken, but I am leary
of adding a new errno return that wasn't possible before.

Comment 4 Jakub Jelinek 2003-02-19 19:01:41 UTC
Ok, then what about instead of errno = EINVAL; return -1; just *alport = 1023; ?
Binding ports in 0 .. 511 area is a bad idea, since legitimate services could
not be started later on due the port taken by rresvport.

Comment 5 Roland McGrath 2003-02-19 19:56:31 UTC
By the currently documented spec, returning EAGAIN is ok.
Wrapping up to 1023 seems fine to me.

Comment 6 Ulrich Drepper 2003-02-21 01:54:12 UTC
I've checked in a change which normalizes the input and wraps around after
looking at port 512.  int/rcmd.c revision 1.64.

Comment 7 Ulrich Drepper 2003-04-22 07:39:33 UTC
glibc 2.3.2-27.9 should behave as we intend it to.  If this is still not what
you want you might have to adjust your expectations.  Give it a try.