Explicitly don't support sets with multiple index types in input/config frameworks

The input framework's Manager::IsCompatibleType() already rejected
sets with multiple index types that aren't all the same (i.e. that are
not pure). Pure ones (e.g. "set[addr,addr]") slipped through and could
cause Zeek to segfault elsewhere in the config framework due to type
comparison subtleties. Note that the ASCII reader can't read such sets
anyway, so this method now rejects sets with any kind of index-type
tuple.

In the config framework, the script-level change handler has a risky
conversion from any to set[bool], which can trigger segfaults when the
underlying set's index is a type tuple. We now prevent this code path
by ensuring it only applies to sets with a single index type.
This commit is contained in:
Christian Kreibich 2021-01-08 19:13:06 -08:00
parent 54b52eb197
commit 421639e7a7
2 changed files with 12 additions and 2 deletions

View file

@ -124,8 +124,13 @@ function format_value(value: any) : string
{ {
local tn = type_name(value); local tn = type_name(value);
local part: string_vec = vector(); local part: string_vec = vector();
if ( /^set/ in tn )
if ( /^set/ in tn && strstr(tn, ",") == 0 )
{ {
# The conversion to set here is tricky and assumes
# that the set isn't indexed via a tuple of types.
# The above check for commas in the type name
# ensures this.
local it: set[bool] = value; local it: set[bool] = value;
for ( sv in it ) for ( sv in it )
part += cat(sv); part += cat(sv);

View file

@ -833,7 +833,12 @@ bool Manager::IsCompatibleType(Type* t, bool atomic_only)
if ( ! t->IsSet() ) if ( ! t->IsSet() )
return false; return false;
return IsCompatibleType(t->AsSetType()->GetIndices()->GetPureType().get(), true); const auto& indices = t->AsSetType()->GetIndices();
if ( indices->GetTypes().size() != 1 )
return false;
return IsCompatibleType(indices->GetPureType().get(), true);
} }
case TYPE_VECTOR: case TYPE_VECTOR: