[PATCH] Don't bind to registered ports in bindresvport
Dan Nicholson
dbn.lists@gmail.com
Thu May 31 15:51:00 GMT 2012
When bindresvport binds to a random port, there's a good chance it will
pick one already registered in services. That's bad since the point of
services is to define well known ports so random programs know which
ones to avoid. The current behavior causes lots of downstream bugs and
requires hacky solutions like running programs early in boot to bind to
desired ports and handing them off when the actual services start.
https://bugzilla.redhat.com/show_bug.cgi?id=103401
Let's just fix the problem at the source. On my fedora system, 295 of
the 541 ports between 512 and 1023 are unregistered. There's plenty of
space to pick a smarter port. If there are systems that require more
random ports than that, bindresvport is probably not the right API to
use.
2012-05-31 Dan Nicholson <dbn.lists@gmail.com>
* sunrpc/bindrsvprt.c (bindresvport): Before binding the port,
make sure it's not registered in services.
---
sunrpc/bindrsvprt.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c
index d493c9f..8594b33 100644
--- a/sunrpc/bindrsvprt.c
+++ b/sunrpc/bindrsvprt.c
@@ -35,6 +35,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netdb.h>
/*
* Bind a socket to a privileged IP port
@@ -74,15 +75,27 @@ bindresvport (int sd, struct sockaddr_in *sin)
int nports = ENDPORT - startport + 1;
int endport = ENDPORT;
+ struct servent serv, *s;
+ char buf[1024];
again:
for (i = 0; i < nports; ++i)
{
sin->sin_port = htons (port++);
if (port > endport)
port = startport;
- res = __bind (sd, sin, sizeof (struct sockaddr_in));
- if (res >= 0 || errno != EADDRINUSE)
- break;
+ __getservbyport_r (sin->sin_port, NULL, &serv, buf, sizeof (buf), &s);
+ if (s != NULL)
+ {
+ /* This port is registered. Fake a return and try the next. */
+ res = -1;
+ __set_errno (EADDRINUSE);
+ }
+ else
+ {
+ res = __bind (sd, sin, sizeof (struct sockaddr_in));
+ if (res >= 0 || errno != EADDRINUSE)
+ break;
+ }
}
if (i == nports && startport != LOWPORT)
--
1.7.7.6
More information about the Libc-alpha
mailing list