From: Alan T. DeKok Date: Sat, 7 Feb 2026 17:28:57 +0000 (-0500) Subject: limit src port ranges to >1024 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e5da11ecb7ba2f4460cb4bbf4ad49e68e201d43;p=thirdparty%2Ffreeradius-server.git limit src port ranges to >1024 and do a few more cleanups. --- diff --git a/src/lib/bio/fd_open.c b/src/lib/bio/fd_open.c index 9ec48679419..4f63a62827a 100644 --- a/src/lib/bio/fd_open.c +++ b/src/lib/bio/fd_open.c @@ -736,32 +736,43 @@ static int fr_bio_fd_socket_bind(fr_bio_fd_t *my, fr_bio_fd_config_t const *cfg) fr_assert((my->info.socket.af == AF_INET) || (my->info.socket.af == AF_INET6)); + /* + * Ranges must be a high value. + */ + if (my->info.cfg->src_port_start && (my->info.cfg->src_port_start < 1024)) { + fr_strerror_const("Cannot set src_port_start in the range 1..1023"); + return -1; + } + #ifdef HAVE_CAPABILITY_H /* - * If we're binding to a special port as non-root, then - * check capabilities. If we're root, we already have - * equivalent capabilities so we don't need to check. + * Source port is in the restricted range, and we're not root, we need to set a capability. + * + * @todo - we really need to call rad_suid_up() and rad_suid_down() here. But those functions + * are in src/lib/server/util.c, and we can't require that libfreeradius-bio is linked to + * libfreeradius-server. */ - if ((my->info.socket.inet.src_port < 1024) && (geteuid() != 0)) { - (void)fr_cap_enable(CAP_NET_BIND_SERVICE, CAP_EFFECTIVE); + if ((my->info.socket.inet.src_port > 0) && (my->info.socket.inet.src_port < 1024) && (geteuid() != 0)); + (void) fr_cap_enable(CAP_NET_BIND_SERVICE, CAP_EFFECTIVE); } #endif if (fr_bio_fd_socket_bind_to_device(my, cfg) < 0) return -1; /* - * Bind to the IP + interface. + * Get the sockaddr for bind() */ if (fr_ipaddr_to_sockaddr(&salocal, &salen, &my->info.socket.inet.src_ipaddr, my->info.socket.inet.src_port) < 0) return -1; /* - * If we have a fixed source port, just use that. + * We don't have a source port range, just bind to whatever source port that we're given. */ - if (my->info.cfg->src_port || !my->info.cfg->src_port_start) { + if (!my->info.cfg->src_port_start) { if (bind(my->info.socket.fd, (struct sockaddr *) &salocal, salen) < 0) { fr_strerror_printf("Failed binding to socket: %s", fr_syserror(errno)); return -1; } + } else { uint16_t src_port, current, range; struct sockaddr_in *sin = (struct sockaddr_in *) &salocal; @@ -816,7 +827,7 @@ static int fr_bio_fd_socket_bind(fr_bio_fd_t *my, fr_bio_fd_config_t const *cfg) } /* - * The source IP may have changed, so get the new one. + * The IP and/or port may have changed, so get the new one. */ done: return fr_bio_fd_socket_name(my);