Fix segmentation fault when parsing sets containing invalid elements.

Currently the destructor would try to free unallocated memory. This
could e.g. be triggered by the input framework reading a set with an
invalid element.
This commit is contained in:
Johanna Amann 2018-01-18 12:32:56 -08:00
parent db6f028003
commit b0be6c90fe
4 changed files with 90 additions and 0 deletions

View file

@ -400,6 +400,9 @@ threading::Value* Ascii::ParseValue(const string& s, const string& name, TypeTag
for ( unsigned int i = 0; i < pos; i++ ) for ( unsigned int i = 0; i < pos; i++ )
delete lvals[i]; delete lvals[i];
// and set the length of the set to 0, otherwhise the destructor will crash.
val->val.vector_val.size = 0;
goto parse_error; goto parse_error;
} }

View file

@ -0,0 +1,8 @@
warning: ../input.log/Input::READER_ASCII: Invalid value for subnet: 127.0.0.1
warning: ../input.log/Input::READER_ASCII: Error while reading set or vector
warning: ../input.log/Input::READER_ASCII: Could not convert line 'name 127.0.0.1' to Val. Ignoring line.
warning: ../input.log/Input::READER_ASCII: Invalid value for subnet: 127.0.0.1
warning: ../input.log/Input::READER_ASCII: Error while reading set or vector
warning: ../input.log/Input::READER_ASCII: Could not convert line 'name 127.0.0.1' to Val. Ignoring line.
received termination signal
>>>

View file

@ -0,0 +1,14 @@
TableErrorEvent, Invalid value for subnet: 127.0.0.1, Reporter::WARNING
TableErrorEvent, Error while reading set or vector, Reporter::WARNING
TableErrorEvent, Could not convert line 'name\x09127.0.0.1' to Val. Ignoring line., Reporter::WARNING
Event, [s={
}]
EventErrorEvent, Invalid value for subnet: 127.0.0.1, Reporter::WARNING
EventErrorEvent, Error while reading set or vector, Reporter::WARNING
EventErrorEvent, Could not convert line 'name\x09127.0.0.1' to Val. Ignoring line., Reporter::WARNING
{
[name] = [s={
}]
}

View file

@ -0,0 +1,65 @@
# @TEST-EXEC: btest-bg-run bro bro -b %INPUT
# @TEST-EXEC: btest-bg-wait 10
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out
# @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline
@TEST-START-FILE input.log
#separator \x09
#fields i s
name -
name 127.0.0.1
@TEST-END-FILE
redef exit_only_after_terminate = T;
redef InputAscii::fail_on_invalid_lines = T;
global outfile: file;
module A;
type Idx: record {
i: string;
};
type Val: record {
s: set[subnet];
};
global endcount: count = 0;
global servers: table[string] of Val = table();
event handle_our_errors(desc: Input::TableDescription, msg: string, level: Reporter::Level)
{
print outfile, "TableErrorEvent", msg, level;
}
event handle_our_errors_event(desc: Input::EventDescription, msg: string, level: Reporter::Level)
{
print outfile, "EventErrorEvent", msg, level;
}
event line(description: Input::EventDescription, tpe: Input::Event, v: Val)
{
print outfile, "Event", v;
}
event bro_init()
{
outfile = open("../out");
# first read in the old stuff into the table...
Input::add_table([$source="../input.log", $name="ssh", $error_ev=handle_our_errors, $idx=Idx, $val=Val, $destination=servers]);
Input::add_event([$source="../input.log", $name="sshevent", $error_ev=handle_our_errors_event, $fields=Val, $want_record=T, $ev=line]);
}
event Input::end_of_data(name: string, source:string)
{
++endcount;
if ( endcount == 2 )
{
print outfile, servers;
terminate();
}
}