fix: dev: Validate -l and -L numeric arguments in named-checkzone

named-checkzone and named-compilezone parsed the -l (max TTL) and -L
(source serial) arguments with strtol(), so a negative value such as
-1 silently became UINT32_MAX and out-of-range values were truncated
to 32 bits without warning; -l in particular appeared to cap TTLs but
no longer enforced anything. Both flags now go through isc_parse_uint32()
and reject any value that is not a valid 32-bit unsigned integer.

Merge branch 'ondrej/named-checkzone-strtol-truncation' into 'main'

See merge request isc-projects/bind9!11900
This commit is contained in:
Ondřej Surý 2026-04-29 17:25:53 +02:00
commit 1064d11af2

View file

@ -24,6 +24,7 @@
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/parseint.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/timer.h>
@ -107,7 +108,6 @@ main(int argc, char **argv) {
bool snset = false;
bool logdump = false;
FILE *errout = stdout;
char *endp;
outputstyle = &dns_master_style_full;
@ -222,22 +222,23 @@ main(int argc, char **argv) {
case 'L':
snset = true;
endp = NULL;
serialnum = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0') {
fprintf(stderr, "source serial number "
"must be numeric");
if (isc_parse_uint32(&serialnum,
isc_commandline_argument,
0) != ISC_R_SUCCESS)
{
fprintf(stderr, "source serial number must be "
"a 32-bit unsigned integer\n");
exit(EXIT_FAILURE);
}
break;
case 'l':
zone_options |= DNS_ZONEOPT_CHECKTTL;
endp = NULL;
maxttl = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0') {
fprintf(stderr, "maximum TTL "
"must be numeric");
if (isc_parse_uint32(&maxttl, isc_commandline_argument,
0) != ISC_R_SUCCESS)
{
fprintf(stderr, "maximum TTL must be a 32-bit "
"unsigned integer\n");
exit(EXIT_FAILURE);
}
break;