Merge remote-tracking branch 'origin/topic/etyp/options-segfault-fix'

* origin/topic/etyp/options-segfault-fix:
  Fix options parsing segfault
This commit is contained in:
Tim Wojtulewicz 2025-01-23 11:49:23 -07:00
commit cc1fdb4203
3 changed files with 22 additions and 2 deletions

14
CHANGES
View file

@ -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 7.2.0-dev.111 | 2025-01-23 11:21:21 -0700
* Minor whitespace cleanup in init-bare.zeek (Tim Wojtulewicz, Corelight) * Minor whitespace cleanup in init-bare.zeek (Tim Wojtulewicz, Corelight)

View file

@ -1 +1 @@
7.2.0-dev.111 7.2.0-dev.113

View file

@ -424,11 +424,17 @@ Options parse_cmdline(int argc, char** argv) {
opterr = 0; opterr = 0;
// getopt may permute the array, so need yet another array // getopt may permute the array, so need yet another array
auto zargs = std::make_unique<char*[]>(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<char*[]>(zeek_args.size() + 1);
for ( size_t i = 0; i < zeek_args.size(); ++i ) for ( size_t i = 0; i < zeek_args.size(); ++i )
zargs[i] = zeek_args[i].data(); 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 ) while ( (op = getopt_long(zeek_args.size(), zargs.get(), opts, long_opts, &long_optsind)) != EOF )
switch ( op ) { switch ( op ) {
case 'a': rval.parse_only = true; break; case 'a': rval.parse_only = true; break;