From: Shawn Routhier Date: Tue, 6 Jan 2009 00:32:19 +0000 (+0000) Subject: Validate argument to port option - bug 18695 X-Git-Tag: v4_2_0a1~115 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59112e84f5b1705578ae7dd71f1a2120ffd0313d;p=thirdparty%2Fdhcp.git Validate argument to port option - bug 18695 --- diff --git a/RELNOTES b/RELNOTES index 72859b9f4..fd2d05155 100644 --- a/RELNOTES +++ b/RELNOTES @@ -47,6 +47,10 @@ The system has only been tested on Linux, FreeBSD, and Solaris, and may not work on other platforms. Please report any problems and suggested fixes to . + Changes since 4.1.0 (bug fixes) + +- Validate the argument to the -p option. + Changes since 4.1.0b1 - A missing "else" in dhcrelay.c could have caused an interface not to diff --git a/client/dhclient.c b/client/dhclient.c index 54e971cc7..c71003997 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -172,7 +172,7 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-p")) { if (++i == argc) usage(); - local_port = htons(atoi(argv[i])); + local_port = validate_port(argv[i]); log_debug("binding to user-specified port %d", ntohs(local_port)); } else if (!strcmp(argv[i], "-d")) { diff --git a/common/inet.c b/common/inet.c index 7bee08881..1d50d40e2 100644 --- a/common/inet.c +++ b/common/inet.c @@ -1,10 +1,10 @@ /* inet.c - Subroutines to manipulate internet addresses in a safely portable + Subroutines to manipulate internet addresses and ports in a safely portable way... */ /* - * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2005,2007,2008 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -604,3 +604,26 @@ piaddrcidr(const struct iaddr *addr, unsigned int bits) { return ret; } +/* Validate that the string represents a valid port number and + * return it in network byte order + */ + +u_int16_t +validate_port(char *port) { + int local_port = 0; + int lower = 1; + int upper = 65535; + char *endptr; + + errno = 0; + local_port = strtol(port, &endptr, 10); + + if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL)) + log_fatal ("Invalid port number specification: %s", port); + + if (local_port < lower || local_port > upper) + log_fatal("Port number specified is out of range (%d-%d).", + lower, upper); + + return htons(local_port); +} diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 3867bd08d..d1ca0fe21 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #else @@ -2450,6 +2451,7 @@ isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result); const char *piaddr PROTO ((struct iaddr)); char *piaddrmask(struct iaddr *, struct iaddr *); char *piaddrcidr(const struct iaddr *, unsigned int); +u_int16_t validate_port(char *); /* dhclient.c */ extern int nowait; diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 93bfb4ed5..e585c900b 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -222,7 +222,7 @@ main(int argc, char **argv) { } else if (!strcmp(argv[i], "-p")) { if (++i == argc) usage(); - local_port = htons(atoi (argv[i])); + local_port = validate_port(argv[i]); log_debug("binding to user-specified port %d", ntohs(local_port)); } else if (!strcmp(argv[i], "-c")) { diff --git a/server/dhcpd.c b/server/dhcpd.c index ff256fe68..3d4d8c0b7 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -298,15 +298,7 @@ main(int argc, char **argv) { if (!strcmp (argv [i], "-p")) { if (++i == argc) usage (); - for (s = argv [i]; *s; s++) - if (!isdigit ((unsigned char)*s)) - log_fatal ("%s: not a valid UDP port", - argv [i]); - status = atoi (argv [i]); - if (status < 1 || status > 65535) - log_fatal ("%s: not a valid UDP port", - argv [i]); - local_port = htons (status); + local_port = validate_port (argv [i]); log_debug ("binding to user-specified port %d", ntohs (local_port)); } else if (!strcmp (argv [i], "-f")) { @@ -531,7 +523,7 @@ main(int argc, char **argv) { if (!local_port) { if ((s = getenv ("DHCPD_PORT"))) { - local_port = htons (atoi (s)); + local_port = validate_port (s); log_debug ("binding to environment-specified port %d", ntohs (local_port)); } else {