diff --git a/CHANGES b/CHANGES index 8232c62691..d8f58185d1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +7.2.0-dev.113 | 2025-01-23 11:49:23 -0700 + + * Fix options parsing segfault (Evan Typanski, Corelight) + + A command like this would segfault: + + zeek -b test.zeek --debug + + The issue was that `getopt_long` was using a null element to determine + what the end of the options array is. If it saw a non-null element after + `--debug` it would say it's the argument for optarg, even if it's beyond + `zeek_args.size()`. Instead, just make sure the array is + null-terminated. + 7.2.0-dev.111 | 2025-01-23 11:21:21 -0700 * Minor whitespace cleanup in init-bare.zeek (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index 2aeb93909b..82dda6b0af 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.2.0-dev.111 +7.2.0-dev.113 diff --git a/src/Options.cc b/src/Options.cc index 9a21eae1d1..de49298435 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -424,11 +424,17 @@ Options parse_cmdline(int argc, char** argv) { opterr = 0; // getopt may permute the array, so need yet another array - auto zargs = std::make_unique(zeek_args.size()); + // + // Make sure this array is one greater than zeek_args and ends in nullptr, otherwise + // getopt may go beyond the end of the array + auto zargs = std::make_unique(zeek_args.size() + 1); for ( size_t i = 0; i < zeek_args.size(); ++i ) zargs[i] = zeek_args[i].data(); + // Make sure getopt doesn't go past the end + zargs[zeek_args.size()] = nullptr; + while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) != EOF ) switch ( op ) { case 'a': rval.parse_only = true; break;