GH-1506: Fix Broker unserialization of set/table function indices

Zeek function types are serialized as a broker::vector, but the
unserialization logic for Zeek set/table types that use a function for
as an index incorrectly identified it as a composite-index, which also
use broker::vector, rather than a singleton-index, and makes such
unserialization fail.

A general example where this failure can happen in practice is when
trying to unserialize a connection record for which there's a
Conn::RemovalHook, since that's a set[function], and a specific case of
that is use of the Intel Framework in a Zeek cluster.
This commit is contained in:
Jon Siwek 2021-04-14 20:39:22 -07:00
parent 0c93e2fcb8
commit d3ace9b7ac
5 changed files with 296 additions and 16 deletions

View file

@ -48,6 +48,22 @@ TEST_CASE("converting Zeek to Broker protocol constants")
namespace zeek::Broker::detail {
// Returns true if the given Zeek type is serialized as a broker::vector
static bool serialized_as_vector(TypeTag tag)
{
switch ( tag ) {
case TYPE_VECTOR:
case TYPE_RECORD:
case TYPE_FUNC:
case TYPE_PATTERN:
case TYPE_OPAQUE:
return true;
default:
return false;
}
return false;
}
static bool data_type_check(const broker::data& d, Type* t);
TransportProto to_zeek_port_proto(broker::port::protocol tp)
@ -216,11 +232,9 @@ struct val_converter {
{
if ( expected_index_types.size() == 1 )
{
auto index_is_vector_or_record =
expected_index_types[0]->Tag() == TYPE_RECORD ||
expected_index_types[0]->Tag() == TYPE_VECTOR;
auto disambiguate = serialized_as_vector(expected_index_types[0]->Tag());
if ( index_is_vector_or_record )
if ( disambiguate )
{
// Disambiguate from composite key w/ multiple vals.
composite_key.emplace_back(move(item));
@ -275,11 +289,9 @@ struct val_converter {
{
if ( expected_index_types.size() == 1 )
{
auto index_is_vector_or_record =
expected_index_types[0]->Tag() == TYPE_RECORD ||
expected_index_types[0]->Tag() == TYPE_VECTOR;
auto disambiguate = serialized_as_vector(expected_index_types[0]->Tag());
if ( index_is_vector_or_record )
if ( disambiguate )
{
// Disambiguate from composite key w/ multiple vals.
composite_key.emplace_back(move(item.first));
@ -606,11 +618,9 @@ struct type_checker {
{
if ( expected_index_types.size() == 1 )
{
auto index_is_vector_or_record =
expected_index_types[0]->Tag() == TYPE_RECORD ||
expected_index_types[0]->Tag() == TYPE_VECTOR;
auto disambiguate = serialized_as_vector(expected_index_types[0]->Tag());
if ( index_is_vector_or_record )
if ( disambiguate )
// Disambiguate from composite key w/ multiple vals.
indices_to_check.emplace_back(&item);
else
@ -665,11 +675,9 @@ struct type_checker {
{
if ( expected_index_types.size() == 1 )
{
auto index_is_vector_or_record =
expected_index_types[0]->Tag() == TYPE_RECORD ||
expected_index_types[0]->Tag() == TYPE_VECTOR;
auto disambiguate = serialized_as_vector(expected_index_types[0]->Tag());
if ( index_is_vector_or_record )
if ( disambiguate )
// Disambiguate from composite key w/ multiple vals.
indices_to_check.emplace_back(&item.first);
else