Add checks to avoid improper negative values use.

This commit is contained in:
Jon Siwek 2013-09-17 16:42:48 -05:00
parent a3b963ad4e
commit a316878d01
12 changed files with 89 additions and 62 deletions

View file

@ -3137,12 +3137,14 @@ FieldExpr::FieldExpr(Expr* arg_op, const char* arg_field_name)
{ {
RecordType* rt = op->Type()->AsRecordType(); RecordType* rt = op->Type()->AsRecordType();
field = rt->FieldOffset(field_name); field = rt->FieldOffset(field_name);
td = rt->FieldDecl(field);
if ( field < 0 ) if ( field < 0 )
ExprError("no such field in record"); ExprError("no such field in record");
else else
{
SetType(rt->FieldType(field)->Ref()); SetType(rt->FieldType(field)->Ref());
td = rt->FieldDecl(field);
}
} }
} }
@ -3852,7 +3854,15 @@ void FieldAssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f)
Val* v = op->Eval(f); Val* v = op->Eval(f);
if ( v ) if ( v )
rec->Assign(rt->FieldOffset(field_name.c_str()), v); {
int idx = rt->FieldOffset(field_name.c_str());
if ( idx < 0 )
reporter->InternalError("Missing record field: %s",
field_name.c_str());
rec->Assign(idx, v);
}
} }
int FieldAssignExpr::IsRecordElement(TypeDecl* td) const int FieldAssignExpr::IsRecordElement(TypeDecl* td) const

View file

@ -2670,6 +2670,16 @@ Val* RecordVal::LookupWithDefault(int field) const
return record_type->FieldDefault(field); return record_type->FieldDefault(field);
} }
Val* RecordVal::Lookup(const char* field, bool with_default) const
{
int idx = record_type->FieldOffset(field);
if ( idx < 0 )
reporter->InternalError("missing record field: %s", field);
return with_default ? LookupWithDefault(idx) : Lookup(idx);
}
RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr, bool allow_orphaning) const
{ {
if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) ) if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) )

View file

@ -895,6 +895,17 @@ public:
Val* Lookup(int field) const; // Does not Ref() value. Val* Lookup(int field) const; // Does not Ref() value.
Val* LookupWithDefault(int field) const; // Does Ref() value. Val* LookupWithDefault(int field) const; // Does Ref() value.
/**
* Looks up the value of a field by field name. If the field doesn't
* exist in the record type, it's an internal error: abort.
* @param field name of field to lookup.
* @param with_default whether to rely on field's &default attribute when
* the field has yet to be initialized.
* @return the value in field \a field. It is Ref()'d only if
* \a with_default is true.
*/
Val* Lookup(const char* field, bool with_default = false) const;
void Describe(ODesc* d) const; void Describe(ODesc* d) const;
// This is an experiment to associate a BroObj within the // This is an experiment to associate a BroObj within the

View file

@ -54,17 +54,19 @@ void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val) void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val)
{ {
// RecordType *connection_type is decleared in NetVar.h // RecordType *connection_type is decleared in NetVar.h
int orig_endp_idx = connection_type->FieldOffset("orig"); RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal();
int resp_endp_idx = connection_type->FieldOffset("resp"); RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal();
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
// endpoint is the RecordType from NetVar.h // endpoint is the RecordType from NetVar.h
// TODO: or orig_endp->Type()->AsRecordVal()->FieldOffset()
int pktidx = endpoint->FieldOffset("num_pkts"); int pktidx = endpoint->FieldOffset("num_pkts");
int bytesidx = endpoint->FieldOffset("num_bytes_ip"); int bytesidx = endpoint->FieldOffset("num_bytes_ip");
// TODO: error handling? if ( pktidx < 0 )
reporter->InternalError("'endpoint' record missing 'num_pkts' field");
if ( bytesidx < 0 )
reporter->InternalError("'endpoint' record missing 'num_bytes_ip' field");
orig_endp->Assign(pktidx, new Val(orig_pkts, TYPE_COUNT)); orig_endp->Assign(pktidx, new Val(orig_pkts, TYPE_COUNT));
orig_endp->Assign(bytesidx, new Val(orig_bytes, TYPE_COUNT)); orig_endp->Assign(bytesidx, new Val(orig_bytes, TYPE_COUNT));
resp_endp->Assign(pktidx, new Val(resp_pkts, TYPE_COUNT)); resp_endp->Assign(pktidx, new Val(resp_pkts, TYPE_COUNT));

View file

@ -440,10 +440,8 @@ void ICMP_Analyzer::Describe(ODesc* d) const
void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val) void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{ {
int orig_endp_idx = connection_type->FieldOffset("orig"); RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal();
int resp_endp_idx = connection_type->FieldOffset("resp"); RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal();
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
UpdateEndpointVal(orig_endp, 1); UpdateEndpointVal(orig_endp, 1);
UpdateEndpointVal(resp_endp, 0); UpdateEndpointVal(resp_endp, 0);

View file

@ -1102,11 +1102,8 @@ void TCP_Analyzer::FlipRoles()
void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{ {
int orig_endp_idx = connection_type->FieldOffset("orig"); RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal();
int resp_endp_idx = connection_type->FieldOffset("resp"); RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal();
RecordVal *orig_endp_val = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp_val = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT)); orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT));
orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT)); orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT));

View file

@ -170,13 +170,9 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
void UDP_Analyzer::UpdateConnVal(RecordVal *conn_val) void UDP_Analyzer::UpdateConnVal(RecordVal *conn_val)
{ {
int orig_endp_idx = connection_type->FieldOffset("orig"); RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal();
int resp_endp_idx = connection_type->FieldOffset("resp"); RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal();
RecordVal *orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
RecordVal *resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
orig_endp = conn_val->Lookup(orig_endp_idx)->AsRecordVal();
resp_endp = conn_val->Lookup(resp_endp_idx)->AsRecordVal();
UpdateEndpointVal(orig_endp, 1); UpdateEndpointVal(orig_endp, 1);
UpdateEndpointVal(resp_endp, 0); UpdateEndpointVal(resp_endp, 0);

View file

@ -20,13 +20,8 @@ DataEvent::DataEvent(RecordVal* args, File* file,
file_analysis::Analyzer* DataEvent::Instantiate(RecordVal* args, File* file) file_analysis::Analyzer* DataEvent::Instantiate(RecordVal* args, File* file)
{ {
using BifType::Record::Files::AnalyzerArgs; Val* chunk_val = args->Lookup("chunk_event");
Val* stream_val = args->Lookup("stream_event");
int chunk_off = AnalyzerArgs->FieldOffset("chunk_event");
int stream_off = AnalyzerArgs->FieldOffset("stream_event");
Val* chunk_val = args->Lookup(chunk_off);
Val* stream_val = args->Lookup(stream_off);
if ( ! chunk_val && ! stream_val ) return 0; if ( ! chunk_val && ! stream_val ) return 0;

View file

@ -33,8 +33,7 @@ Extract::~Extract()
static Val* get_extract_field_val(RecordVal* args, const char* name) static Val* get_extract_field_val(RecordVal* args, const char* name)
{ {
using BifType::Record::Files::AnalyzerArgs; Val* rval = args->Lookup(name);
Val* rval = args->Lookup(AnalyzerArgs->FieldOffset(name));
if ( ! rval ) if ( ! rval )
reporter->Error("File extraction analyzer missing arg field: %s", name); reporter->Error("File extraction analyzer missing arg field: %s", name);

View file

@ -296,7 +296,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
return false; return false;
} }
Val* name_val = description->LookupWithDefault(rtype->FieldOffset("name")); Val* name_val = description->Lookup("name", true);
string name = name_val->AsString()->CheckString(); string name = name_val->AsString()->CheckString();
Unref(name_val); Unref(name_val);
@ -308,10 +308,10 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
return false; return false;
} }
EnumVal* reader = description->LookupWithDefault(rtype->FieldOffset("reader"))->AsEnumVal(); EnumVal* reader = description->Lookup("reader", true)->AsEnumVal();
// get the source ... // get the source ...
Val* sourceval = description->LookupWithDefault(rtype->FieldOffset("source")); Val* sourceval = description->Lookup("source", true);
assert ( sourceval != 0 ); assert ( sourceval != 0 );
const BroString* bsource = sourceval->AsString(); const BroString* bsource = sourceval->AsString();
string source((const char*) bsource->Bytes(), bsource->Len()); string source((const char*) bsource->Bytes(), bsource->Len());
@ -321,7 +321,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
rinfo.source = copy_string(source.c_str()); rinfo.source = copy_string(source.c_str());
rinfo.name = copy_string(name.c_str()); rinfo.name = copy_string(name.c_str());
EnumVal* mode = description->LookupWithDefault(rtype->FieldOffset("mode"))->AsEnumVal(); EnumVal* mode = description->Lookup("mode", true)->AsEnumVal();
switch ( mode->InternalInt() ) switch ( mode->InternalInt() )
{ {
case 0: case 0:
@ -342,7 +342,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
Unref(mode); Unref(mode);
Val* config = description->LookupWithDefault(rtype->FieldOffset("config")); Val* config = description->Lookup("config", true);
info->config = config->AsTableVal(); // ref'd by LookupWithDefault info->config = config->AsTableVal(); // ref'd by LookupWithDefault
{ {
@ -401,11 +401,11 @@ bool Manager::CreateEventStream(RecordVal* fval)
} }
RecordType *fields = fval->LookupWithDefault(rtype->FieldOffset("fields"))->AsType()->AsTypeType()->Type()->AsRecordType(); RecordType *fields = fval->Lookup("fields", true)->AsType()->AsTypeType()->Type()->AsRecordType();
Val *want_record = fval->LookupWithDefault(rtype->FieldOffset("want_record")); Val *want_record = fval->Lookup("want_record", true);
Val* event_val = fval->LookupWithDefault(rtype->FieldOffset("ev")); Val* event_val = fval->Lookup("ev", true);
Func* event = event_val->AsFunc(); Func* event = event_val->AsFunc();
Unref(event_val); Unref(event_val);
@ -547,18 +547,18 @@ bool Manager::CreateTableStream(RecordVal* fval)
} }
} }
Val* pred = fval->LookupWithDefault(rtype->FieldOffset("pred")); Val* pred = fval->Lookup("pred", true);
RecordType *idx = fval->LookupWithDefault(rtype->FieldOffset("idx"))->AsType()->AsTypeType()->Type()->AsRecordType(); RecordType *idx = fval->Lookup("idx", true)->AsType()->AsTypeType()->Type()->AsRecordType();
RecordType *val = 0; RecordType *val = 0;
if ( fval->LookupWithDefault(rtype->FieldOffset("val")) != 0 ) if ( fval->Lookup("val", true) != 0 )
{ {
val = fval->LookupWithDefault(rtype->FieldOffset("val"))->AsType()->AsTypeType()->Type()->AsRecordType(); val = fval->Lookup("val", true)->AsType()->AsTypeType()->Type()->AsRecordType();
Unref(val); // The lookupwithdefault in the if-clause ref'ed val. Unref(val); // The lookupwithdefault in the if-clause ref'ed val.
} }
TableVal *dst = fval->LookupWithDefault(rtype->FieldOffset("destination"))->AsTableVal(); TableVal *dst = fval->Lookup("destination", true)->AsTableVal();
// check if index fields match table description // check if index fields match table description
int num = idx->NumFields(); int num = idx->NumFields();
@ -588,9 +588,9 @@ bool Manager::CreateTableStream(RecordVal* fval)
return false; return false;
} }
Val *want_record = fval->LookupWithDefault(rtype->FieldOffset("want_record")); Val *want_record = fval->Lookup("want_record", true);
Val* event_val = fval->LookupWithDefault(rtype->FieldOffset("ev")); Val* event_val = fval->Lookup("ev", true);
Func* event = event_val ? event_val->AsFunc() : 0; Func* event = event_val ? event_val->AsFunc() : 0;
Unref(event_val); Unref(event_val);

View file

@ -295,7 +295,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval)
return false; return false;
} }
RecordType* columns = sval->Lookup(rtype->FieldOffset("columns")) RecordType* columns = sval->Lookup("columns")
->AsType()->AsTypeType()->Type()->AsRecordType(); ->AsType()->AsTypeType()->Type()->AsRecordType();
bool log_attr_present = false; bool log_attr_present = false;
@ -322,7 +322,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval)
return false; return false;
} }
Val* event_val = sval->Lookup(rtype->FieldOffset("ev")); Val* event_val = sval->Lookup("ev");
Func* event = event_val ? event_val->AsFunc() : 0; Func* event = event_val ? event_val->AsFunc() : 0;
if ( event ) if ( event )
@ -579,19 +579,18 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval)
return false; return false;
// Find the right writer type. // Find the right writer type.
int idx = rtype->FieldOffset("writer"); EnumVal* writer = fval->Lookup("writer", true)->AsEnumVal();
EnumVal* writer = fval->LookupWithDefault(idx)->AsEnumVal();
// Create a new Filter instance. // Create a new Filter instance.
Val* name = fval->LookupWithDefault(rtype->FieldOffset("name")); Val* name = fval->Lookup("name", true);
Val* pred = fval->LookupWithDefault(rtype->FieldOffset("pred")); Val* pred = fval->Lookup("pred", true);
Val* path_func = fval->LookupWithDefault(rtype->FieldOffset("path_func")); Val* path_func = fval->Lookup("path_func", true);
Val* log_local = fval->LookupWithDefault(rtype->FieldOffset("log_local")); Val* log_local = fval->Lookup("log_local", true);
Val* log_remote = fval->LookupWithDefault(rtype->FieldOffset("log_remote")); Val* log_remote = fval->Lookup("log_remote", true);
Val* interv = fval->LookupWithDefault(rtype->FieldOffset("interv")); Val* interv = fval->Lookup("interv", true);
Val* postprocessor = fval->LookupWithDefault(rtype->FieldOffset("postprocessor")); Val* postprocessor = fval->Lookup("postprocessor", true);
Val* config = fval->LookupWithDefault(rtype->FieldOffset("config")); Val* config = fval->Lookup("config", true);
Filter* filter = new Filter; Filter* filter = new Filter;
filter->name = name->AsString()->CheckString(); filter->name = name->AsString()->CheckString();
@ -616,8 +615,8 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval)
// Build the list of fields that the filter wants included, including // Build the list of fields that the filter wants included, including
// potentially rolling out fields. // potentially rolling out fields.
Val* include = fval->Lookup(rtype->FieldOffset("include")); Val* include = fval->Lookup("include");
Val* exclude = fval->Lookup(rtype->FieldOffset("exclude")); Val* exclude = fval->Lookup("exclude");
filter->num_fields = 0; filter->num_fields = 0;
filter->fields = 0; filter->fields = 0;
@ -631,7 +630,7 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval)
} }
// Get the path for the filter. // Get the path for the filter.
Val* path_val = fval->Lookup(rtype->FieldOffset("path")); Val* path_val = fval->Lookup("path");
if ( path_val ) if ( path_val )
{ {

View file

@ -1261,6 +1261,16 @@ void _set_processing_status(const char* status)
int fd = open(proc_status_file, O_CREAT | O_WRONLY | O_TRUNC, 0700); int fd = open(proc_status_file, O_CREAT | O_WRONLY | O_TRUNC, 0700);
if ( fd < 0 )
{
char buf[256];
strerror_r(errno, buf, sizeof(buf));
reporter->Error("Failed to open process status file '%s': %s",
proc_status_file, buf);
errno = old_errno;
return;
}
int len = strlen(status); int len = strlen(status);
while ( len ) while ( len )
{ {