Bugzilla will be upgraded to version 5.0 on a still to be determined date in the near future. The original upgrade date has been delayed.
Bug 78295 - rresvport wraps socket number
rresvport wraps socket number
Product: Red Hat Linux
Classification: Retired
Component: glibc (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
Depends On:
  Show dependency treegraph
Reported: 2002-11-20 16:04 EST by Ben Woodard
Modified: 2016-11-24 10:05 EST (History)
4 users (show)

See Also:
Fixed In Version: 2.3.2-27.9
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2003-04-22 03:39:33 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description Ben Woodard 2002-11-20 16:04:24 EST
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 16:10:24 EST
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 12:59:37 EST
E.g. http://www.mkssoftware.com/docs/man3/rcmd.3.asp documents that the caller
must pass an argument between 512 and 1023 inclusive.
Likewise http://conx.bu.edu/cgi-bin/perl/manscript?ruserok(3)
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 13:57:39 EST
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 14:01:41 EST
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 14:56:31 EST
By the currently documented spec, returning EAGAIN is ok.
Wrapping up to 1023 seems fine to me.
Comment 6 Ulrich Drepper 2003-02-20 20:54:12 EST
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 03:39:33 EDT
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.

Note You need to log in before you can comment on or make changes to this bug.