1 Patch from the OpenSUSE glibc
4 sunrpc/bindrsvprt.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++----
5 1 file changed, 99 insertions(+), 8 deletions(-)
7 --- a/sunrpc/bindrsvprt.c
8 +++ b/sunrpc/bindrsvprt.c
10 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
23 +#define STARTPORT 600
25 +#define ENDPORT (IPPORT_RESERVED - 1)
26 +#define NPORTS (ENDPORT - STARTPORT + 1)
29 + * Read the file /etc/rpc.blacklisted, so that we don't bind
33 +static int blacklist_read;
35 +static int list_size = 0;
38 +load_blacklist (void)
43 + int size = 0, ptr = 0;
47 + fp = fopen ("/etc/bindresvport.blacklist", "r");
55 + ssize_t n = __getline (&buf, &buflen, fp);
60 + tmp = strchr (cp, '#'); /* remove comments */
63 + while (isspace ((int)*cp)) /* remove spaces and tabs */
65 + if (*cp == '\0') /* ignore empty lines */
67 + if (cp[strlen (cp) - 1] == '\n')
68 + cp[strlen (cp) - 1] = '\0';
70 + port = strtoul (cp, &tmp, 0);
71 + while (isspace(*tmp))
73 + if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE))
76 + /* Don't bother with out-of-range ports */
77 + if (port < LOWPORT || port > ENDPORT)
83 + list = realloc (list, size * sizeof (int));
103 * Bind a socket to a privileged IP port
106 bindresvport (int sd, struct sockaddr_in *sin)
108 + static short startport = STARTPORT;
110 struct sockaddr_in myaddr;
113 -#define STARTPORT 600
115 -#define ENDPORT (IPPORT_RESERVED - 1)
116 -#define NPORTS (ENDPORT - STARTPORT + 1)
117 - static short startport = STARTPORT;
118 + if (!blacklist_read)
121 if (sin == (struct sockaddr_in *) 0)
124 port = (__getpid () % NPORTS) + STARTPORT;
127 + __set_errno (EADDRINUSE);
128 /* Initialize to make gcc happy. */
133 for (i = 0; i < nports; ++i)
135 - sin->sin_port = htons (port++);
136 - if (port > endport)
140 + sin->sin_port = htons (port);
142 + /* Check, if this port is not blacklisted. */
143 + for (j = 0; j < list_size; j++)
144 + if (port == list[j])
145 + goto try_next_port;
147 res = __bind (sd, sin, sizeof (struct sockaddr_in));
148 if (res >= 0 || errno != EADDRINUSE)
152 + if (++port > endport)
156 if (i == nports && startport != LOWPORT)