don't treat numeric port strings as servent records in getservby*()
authorRich Felker <dalias@aerifal.cx>
Thu, 7 Sep 2017 01:42:15 +0000 (21:42 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 7 Sep 2017 01:42:15 +0000 (21:42 -0400)
some applications use getservbyport to find port numbers that are not
assigned to a service; if getservbyport always succeeds with a numeric
string as the result, they fail to find any available ports.

POSIX doesn't seem to mandate the behavior one way or another. it
specifies an abstract service database, which an implementation could
define to include numeric port strings, but it makes more sense to
align behavior with traditional implementations.

based on patch by A. Wilcox. the original patch only changed
getservbyport[_r]. to maintain a consistent view of the "service
database", I have also modified getservbyname[_r] to exclude numeric
port strings.

src/network/getservbyname_r.c
src/network/getservbyport_r.c

index ad3d6164c2e1c63089376f8fa53340ca553ef57e..cad6317ab84243e5bc8de3a1d8ce17eb4a688a5e 100644 (file)
@@ -5,6 +5,7 @@
 #include <inttypes.h>
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 #include "lookup.h"
 
 #define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
@@ -17,6 +18,11 @@ int getservbyname_r(const char *name, const char *prots,
 
        *res = 0;
 
+       /* Don't treat numeric port number strings as service records. */
+       char *end = "";
+       strtoul(name, &end, 10);
+       if (!*end) return ENOENT;
+
        /* Align buffer */
        align = -(uintptr_t)buf & ALIGN-1;
        if (buflen < 2*sizeof(char *)+align)
index 0ae0e41587fe03f36708583edd6596195d0ce25d..b7f21c6b398a52c4eeb61ea9a94f12a1e88e7b71 100644 (file)
@@ -5,6 +5,7 @@
 #include <inttypes.h>
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 
 int getservbyport_r(int port, const char *prots,
        struct servent *se, char *buf, size_t buflen, struct servent **res)
@@ -51,6 +52,9 @@ int getservbyport_r(int port, const char *prots,
                break;
        }
 
+       /* A numeric port string is not a service record. */
+       if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT;
+
        *res = se;
        return 0;
 }