[PATCH RFC] Make bindresvport(3) avoid IANA-assigned ports

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There have been complaints over many years that bindresvport(3) can
bind to a reserved port that is also assigned to a well-known
service, preventing that service from starting as long as bindresv-
port's caller is still squatting on that port.  For instance:

https://sourceware.org/bugzilla/show_bug.cgi?id=1014
https://bugzilla.redhat.com/show_bug.cgi?id=103401
https://bugzilla.novell.com/show_bug.cgi?id=262341
https://bugs.debian.org/638322
http://cyberelk.net/tim/software/portreserve/
https://sources.debian.org/src/glibc/2.26-3/debian/patches/any/local-bindresvport_blacklist.diff/

statd, for example, has a long-running downcall client that can
squat on a reserved port for as long as the system is up. statd is
courteous enough to try hard to avoid choosing a well-known port
for its downcall client.

bindresvport(3) is a generic API, and therefore can't simply skip
all ports assigned in /etc/services, as that leaves a pretty skimpy
set of remaining ports that can be used.

An explicit blacklist might be used to prevent the use of just a
few common services. Although /etc/bindresvport.blacklist is
historically supported on several distributions, there have been
some objections to that approach in the long term:

- It should be improved by making the blacklist a directory (say,
  /etc/bindresvport.blacklist.d/) so that other packages can
  easily insert new blacklisted ports when they are installed.

- But it would be even nicer if there wasn't an additional adminis-
  trative interface, particularly one that largely duplicates what
  is already in /etc/services .

Thus I'm proposing a slightly different approach: Change bindresv-
port(3) so it tries to skip IANA-assigned ports; if no unused port
is found, search again, but allow the use of IANA-assigned ports
this time.

This gives reasonable avoidance behavior but still allows operation
when the set of unassigned ports runs out, and does not introduce
another administrative interface.

See also commit c254b435007e.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---
 src/bindresvport.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Hi Naruto-

Please apply this patch to the latest libtirpc source tree. Rebuild
it, then "sudo make install". Then rebuild rpcinfo to pull in the
rebuilt version of libtirpc.

diff --git a/src/bindresvport.c b/src/bindresvport.c
index 2d8f2bc..6423afb 100644
--- a/src/bindresvport.c
+++ b/src/bindresvport.c
@@ -85,6 +85,7 @@ bindresvport_sa(sd, sa)
 	socklen_t salen;
 	int nports;
 	int endport = ENDPORT;
+	int pass;
 	int i;
 
 	mutex_lock(&port_lock);
@@ -130,11 +131,15 @@ bindresvport_sa(sd, sa)
         }
         res = -1;
         errno = EADDRINUSE;
-		again:
+        pass = 1;
+	setservent(1);
+again:
         for (i = 0; i < nports; ++i) {
                 *portp = htons(port++);
                  if (port > endport) 
                         port = startport;
+		if (pass == 1 && getservbyport(*portp, NULL))
+			continue;
                 res = bind(sd, sa, salen);
 		if (res >= 0 || errno != EADDRINUSE)
 	                break;
@@ -144,8 +149,10 @@ bindresvport_sa(sd, sa)
 	    endport = STARTPORT - 1;
 	    nports = STARTPORT - LOWPORT;
 	    port = LOWPORT + port % (STARTPORT - LOWPORT);
+	    pass++;
 	    goto again;
 	}
+	endservent();
 	mutex_unlock(&port_lock);
 
         return (res);

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux