diff --git a/CHANGES b/CHANGES index c58792e1f3..257c6f707e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,31 @@ +4.1.0-dev.125 | 2021-01-21 11:27:14 +0000 + + * More precise type information in a config framework error message + + When an option's value is a reader-incompatible table or set, Zeek now + renders the type as expressed in the script layer (e.g. "set[addr,addr]") + as opposed to the internal type tag (which'd here be "table", including + for sets). (Christian Kreibich, Corelight) + + * 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. + (Christian Kreibich, Corelight) + + * Fix logo/website link in README (Jon Siwek, Corelight) + 4.1.0-dev.120 | 2021-01-19 21:08:11 -0800 * Update Cirrus CI naming for MacOS images (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index e8aa901a0d..e156beb0c1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.0-dev.120 +4.1.0-dev.125 diff --git a/scripts/base/frameworks/config/main.zeek b/scripts/base/frameworks/config/main.zeek index e2cfb11c8a..5fe7f6eaaf 100644 --- a/scripts/base/frameworks/config/main.zeek +++ b/scripts/base/frameworks/config/main.zeek @@ -124,8 +124,13 @@ function format_value(value: any) : string { local tn = type_name(value); 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; for ( sv in it ) part += cat(sv); diff --git a/src/input/Manager.cc b/src/input/Manager.cc index 359b3ef222..6a8b4ac4eb 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -832,7 +832,12 @@ bool Manager::IsCompatibleType(Type* t, bool atomic_only) if ( ! t->IsSet() ) 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: diff --git a/src/input/readers/config/Config.cc b/src/input/readers/config/Config.cc index 0a3d33811c..ec6226de99 100644 --- a/src/input/readers/config/Config.cc +++ b/src/input/readers/config/Config.cc @@ -10,6 +10,7 @@ #include #include +#include "zeek/Desc.h" #include "zeek/input/Manager.h" #include "zeek/threading/SerialTypes.h" @@ -38,7 +39,7 @@ Config::Config(ReaderFrontend *frontend) : ReaderBackend(frontend) if ( id->GetType()->Tag() == TYPE_RECORD || ! Manager::IsCompatibleType(id->GetType().get()) ) { - option_types[id->Name()] = std::make_tuple(TYPE_ERROR, id->GetType()->Tag()); + option_types[id->Name()] = std::make_tuple(TYPE_ERROR, id->GetType()->Tag(), id); continue; } @@ -49,7 +50,7 @@ Config::Config(ReaderFrontend *frontend) : ReaderBackend(frontend) else if ( primary == TYPE_VECTOR ) secondary = id->GetType()->AsVectorType()->Yield()->Tag(); - option_types[id->Name()] = std::make_tuple(primary, secondary); + option_types[id->Name()] = std::make_tuple(primary, secondary, id); } } @@ -212,8 +213,10 @@ bool Config::DoUpdate() if ( std::get<0>((*typeit).second) == TYPE_ERROR ) { + ODesc d; + std::get<2>((*typeit).second)->GetType()->Describe(&d); Warning(Fmt("Option '%s' has type '%s', which is not supported for file input. Ignoring line.", - key.c_str(), type_name(std::get<1>((*typeit).second)))); + key.c_str(), d.Description())); continue; } diff --git a/src/input/readers/config/Config.h b/src/input/readers/config/Config.h index c8e8360ccd..fe525c66ad 100644 --- a/src/input/readers/config/Config.h +++ b/src/input/readers/config/Config.h @@ -9,6 +9,7 @@ #include #include +#include "zeek/ID.h" #include "zeek/input/ReaderBackend.h" #include "zeek/threading/formatters/Ascii.h" @@ -50,7 +51,7 @@ private: std::string empty_field; std::unique_ptr formatter; - std::unordered_map> option_types; + std::unordered_map> option_types; std::unordered_map option_values; }; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.config.errors/errout b/testing/btest/Baseline/scripts.base.frameworks.input.config.errors/errout index 8f72c4b0c2..386257a5df 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.config.errors/errout +++ b/testing/btest/Baseline/scripts.base.frameworks.input.config.errors/errout @@ -10,6 +10,6 @@ warning: Value 'unknown' for source 'thread ../configfile/Input::READER_CONFIG' error: SendEvent for event InputConfig::new_value failed warning: ../configfile/Input::READER_CONFIG: Option 'testbooool' does not exist. Ignoring line. warning: ../configfile/Input::READER_CONFIG: Option 'test_any' has type 'any', which is not supported for file input. Ignoring line. -warning: ../configfile/Input::READER_CONFIG: Option 'test_table' has type 'table', which is not supported for file input. Ignoring line. +warning: ../configfile/Input::READER_CONFIG: Option 'test_table' has type 'table[string] of string', which is not supported for file input. Ignoring line. received termination signal >>>