From 95b29d5695b89b099b523df4877c66afa58f0575 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 3 Nov 2021 09:50:53 +0000 Subject: [PATCH 1/4] nutscan-ip.c, nut-scanner.c: instrument the CIDR processing to trace an error --- tools/nut-scanner/nut-scanner.c | 3 +++ tools/nut-scanner/nutscan-ip.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index e2e5a4474b..c24ae87d62 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -300,6 +300,7 @@ int main(int argc, char *argv[]) break; case 'm': cidr = strdup(optarg); + upsdebugx(5, "Got CIDR net/mask: %s", cidr); break; case 'D': /* nothing to do, here */ @@ -475,7 +476,9 @@ int main(int argc, char *argv[]) } if (cidr) { + upsdebugx(1, "Processing CIDR net/mask: %s", cidr); nutscan_cidr_to_ip(cidr, &start_ip, &end_ip); + upsdebugx(1, "Extracted IP address range from CIDR net/mask: %s => %s", start_ip, end_ip); } if (!allow_usb && !allow_snmp && !allow_xml && !allow_oldnut && diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c index 6b8fcaf39b..7e55345eb2 100644 --- a/tools/nut-scanner/nutscan-ip.c +++ b/tools/nut-scanner/nutscan-ip.c @@ -269,15 +269,23 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) first_ip = strdup(strtok_r(cidr_tok, "/", &saveptr)); free(cidr_tok); if (first_ip == NULL) { + upsdebugx(0, "WARNING: %s failed to parse first_ip from cidr=%s", + __func__, cidr); return 0; } mask = strtok_r(NULL, "/", &saveptr); if (mask == NULL) { + upsdebugx(0, "WARNING: %s failed to parse mask from cidr=%s (first_ip=%s)", + __func__, cidr, first_ip); free (first_ip); return 0; } + upsdebugx(0, "%s: parsed cidr=%s into first_ip=%s and mask=%s", + __func__, cidr, first_ip, mask); mask_val = atoi(mask); + upsdebugx(0, "%s: parsed mask value %d", + __func__, mask_val); /* Detecting IPv4 vs IPv6 */ memset(&hints, 0, sizeof(struct addrinfo)); From d97f1e0336ebf2d1c15763125ddfc2a3787bf178 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 3 Nov 2021 11:47:34 +0000 Subject: [PATCH 2/4] tools/nut-scanner/nutscan-ip.c: only free cidr_tok after we are done manipulating its memory buffer --- tools/nut-scanner/nutscan-ip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c index 7e55345eb2..046bb18c8e 100644 --- a/tools/nut-scanner/nutscan-ip.c +++ b/tools/nut-scanner/nutscan-ip.c @@ -267,10 +267,10 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) cidr_tok = strdup(cidr); first_ip = strdup(strtok_r(cidr_tok, "/", &saveptr)); - free(cidr_tok); if (first_ip == NULL) { upsdebugx(0, "WARNING: %s failed to parse first_ip from cidr=%s", __func__, cidr); + free(cidr_tok); return 0; } mask = strtok_r(NULL, "/", &saveptr); @@ -278,6 +278,7 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) upsdebugx(0, "WARNING: %s failed to parse mask from cidr=%s (first_ip=%s)", __func__, cidr, first_ip); free (first_ip); + free(cidr_tok); return 0; } upsdebugx(0, "%s: parsed cidr=%s into first_ip=%s and mask=%s", @@ -287,6 +288,8 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) upsdebugx(0, "%s: parsed mask value %d", __func__, mask_val); + free(cidr_tok); + /* Detecting IPv4 vs IPv6 */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; From e1c6dee1a528b73a3ee4b2da041fa5b9f8df4db9 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 3 Nov 2021 11:49:38 +0000 Subject: [PATCH 3/4] tools/nut-scanner/nutscan-ip.c: tone down the debug-logging of CIDR processing --- tools/nut-scanner/nutscan-ip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c index 046bb18c8e..91eb4004e2 100644 --- a/tools/nut-scanner/nutscan-ip.c +++ b/tools/nut-scanner/nutscan-ip.c @@ -281,11 +281,11 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) free(cidr_tok); return 0; } - upsdebugx(0, "%s: parsed cidr=%s into first_ip=%s and mask=%s", + upsdebugx(5, "%s: parsed cidr=%s into first_ip=%s and mask=%s", __func__, cidr, first_ip, mask); mask_val = atoi(mask); - upsdebugx(0, "%s: parsed mask value %d", + upsdebugx(5, "%s: parsed mask value %d", __func__, mask_val); free(cidr_tok); From 3a8fe31ba062f473d32f95c562f8d975555f46aa Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 3 Nov 2021 12:40:55 +0000 Subject: [PATCH 4/4] tools/nut-scanner/nutscan-ip.c: nutscan_cidr_to_ip(): forbid scanning whole Internet --- tools/nut-scanner/nutscan-ip.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c index 91eb4004e2..fb344d95da 100644 --- a/tools/nut-scanner/nutscan-ip.c +++ b/tools/nut-scanner/nutscan-ip.c @@ -288,6 +288,16 @@ int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) upsdebugx(5, "%s: parsed mask value %d", __func__, mask_val); + /* NOTE: Sanity-wise, some larger number also makes sense + * as the maximum subnet size we would scan. But at least, + * this helps avoid scanning the whole Internet just due + * to string-parsing errors. + */ + if (mask_val < 1) { + fatalx(EXIT_FAILURE, "Bad netmask: %s", mask); + } + + /* Note: this freeing invalidates "mask" and "saveptr" pointer targets */ free(cidr_tok); /* Detecting IPv4 vs IPv6 */