From: Olaf Kirch Subject: make libtirpc honor /etc/bindresvport.blacklist Signed-off-by: Olaf Kirch --- src/bindresvport.c +++ src/bindresvport.c 2014/12/15 13:29:13 @@ -39,7 +39,10 @@ #include +#include +#include #include +#include #include #include @@ -68,6 +71,80 @@ #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) +/* + * Read the file /etc/bindresvport.blacklist, so that we don't bind + * to these ports. + */ + +static int blacklist_read; +static int *list; +static int list_size = 0; + +static void +load_blacklist (void) +{ + FILE *fp; + char *buf = NULL; + size_t buflen = 0; + int size = 0, ptr = 0; + + blacklist_read = 1; + + fp = fopen ("/etc/bindresvport.blacklist", "r"); + if (NULL == fp) + return; + + while (!feof (fp)) + { + unsigned long port; + char *tmp, *cp; + ssize_t n = getline (&buf, &buflen, fp); + if (n < 1) + break; + + cp = buf; + tmp = strchr (cp, '#'); /* remove comments */ + if (tmp) + *tmp = '\0'; + while (isspace ((int)*cp)) /* remove spaces and tabs */ + ++cp; + if (*cp == '\0') /* ignore empty lines */ + continue; + if (cp[strlen (cp) - 1] == '\n') + cp[strlen (cp) - 1] = '\0'; + + port = strtoul (cp, &tmp, 0); + while (isspace(*tmp)) + ++tmp; + if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE)) + continue; + + /* Don't bother with out-of-range ports */ + if (port < LOWPORT || port > ENDPORT) + continue; + + if (ptr >= size) + { + size += 10; + list = realloc (list, size * sizeof (int)); + if (list == NULL) + { + free (buf); + return; + } + } + + list[ptr++] = port; + } + + fclose (fp); + + if (buf) + free (buf); + + list_size = ptr; +} + int bindresvport_sa(sd, sa) int sd; @@ -87,6 +164,9 @@ int endport = ENDPORT; int i; + if (!blacklist_read) + load_blacklist(); + mutex_lock(&port_lock); nports = ENDPORT - startport + 1; @@ -132,12 +212,21 @@ errno = EADDRINUSE; again: for (i = 0; i < nports; ++i) { - *portp = htons(port++); - if (port > endport) - port = startport; - res = bind(sd, sa, salen); + int j; + + /* Check if this port is not blacklisted. */ + for (j = 0; j < list_size; j++) + if (port == list[j]) + goto try_next_port; + + *portp = htons(port); + res = bind(sd, sa, salen); if (res >= 0 || errno != EADDRINUSE) break; + +try_next_port: + if (++port > endport) + port = startport; } if (i == nports && startport != LOWPORT) { startport = LOWPORT;