From 0210f16cf1bd2f87b7fe4336311c6dfd88030f8b Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 16 Apr 2007 11:15:40 +1000 Subject: [PATCH] Be more cautious about use for privilege ports (<1024). Ports < 1024 are a scarce resource and should not be used carelessly. Technically they should be not used at all without registration with IANA, but sometimes we need them despite that. So: for the socket that RPC services listen on, don't use a <1024 port by default. There is no need. For sockets that we send messages on, that are long-lived, and that might need to appear 'privileged', avoid using a number that is registered in /etc/services if possible. --- support/nfs/svc_socket.c | 3 --- utils/statd/rmtcall.c | 34 +++++++++++++++++++++++----------- utils/statd/sm-notify.c | 10 ++++++++++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/support/nfs/svc_socket.c b/support/nfs/svc_socket.c index 6799d16..f44217a 100644 --- a/support/nfs/svc_socket.c +++ b/support/nfs/svc_socket.c @@ -101,8 +101,6 @@ svc_socket (u_long number, int type, int protocol, int reuse) } else { - if (bindresvport (sock, &addr)) - { addr.sin_port = 0; if (bind (sock, (struct sockaddr *) &addr, len) < 0) { @@ -110,7 +108,6 @@ svc_socket (u_long number, int type, int protocol, int reuse) (void) __close (sock); sock = -1; } - } } if (sock >= 0) diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c index 816a6f3..eb1919a 100644 --- a/utils/statd/rmtcall.c +++ b/utils/statd/rmtcall.c @@ -62,25 +62,37 @@ int statd_get_socket(void) { struct sockaddr_in sin; + struct servent *se; + int loopcnt = 100; if (sockfd >= 0) return sockfd; - if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - note(N_CRIT, "Can't create socket: %m"); - return -1; - } + while (loopcnt-- > 0) { - FD_SET(sockfd, &SVC_FDSET); + if (sockfd >= 0) close(sockfd); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; + if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + note(N_CRIT, "Can't create socket: %m"); + return -1; + } - if (bindresvport(sockfd, &sin) < 0) { - dprintf(N_WARNING, - "process_hosts: can't bind to reserved port\n"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + + if (bindresvport(sockfd, &sin) < 0) { + dprintf(N_WARNING, + "process_hosts: can't bind to reserved port\n"); + break; + } + se = getservbyport(sin.sin_port, "udp"); + if (se == NULL) + break; + /* rather not use that port, try again */ } + FD_SET(sockfd, &SVC_FDSET); return sockfd; } diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c index bb6c2ef..1059a88 100644 --- a/utils/statd/sm-notify.c +++ b/utils/statd/sm-notify.c @@ -215,7 +215,9 @@ notify(void) nsm_address local_addr; time_t failtime = 0; int sock = -1; + int retry_cnt = 0; + retry: sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("socket"); @@ -248,7 +250,15 @@ notify(void) exit(1); } } else { + struct servent *se; (void) bindresvport(sock, (struct sockaddr_in *) &local_addr); + /* try to avoid known ports */ + se = getservbyport(local_addr.sin_port, "udp"); + if (se && retry_cnt < 100) { + retry_cnt++; + close(sock); + goto retry; + } } if (opt_max_retry) -- 2.39.2