Memory leak fixes for bad usages of VectorVal ctor.

Many usages of the VectorVal ctor didn't account for the fact that
it automatically Ref's the VectorType argument and end up leaking it.
This commit is contained in:
Jon Siwek 2012-06-06 11:50:15 -05:00
parent 89cb103a2c
commit 7599ac8f31
8 changed files with 100 additions and 15 deletions

View file

@ -977,6 +977,9 @@ type ip6_option: record {
data: string; ##< Option data.
};
## A type alias for a vector of IPv6 options.
type ip6_options: vector of ip6_option;
## Values extracted from an IPv6 Hop-by-Hop options extension header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_hdr ip6_ext_hdr ip6_option
@ -987,7 +990,7 @@ type ip6_hopopts: record {
## Length of header in 8-octet units, excluding first unit.
len: count;
## The TLV encoded options;
options: vector of ip6_option;
options: ip6_options;
};
## Values extracted from an IPv6 Destination options extension header.
@ -1000,7 +1003,7 @@ type ip6_dstopts: record {
## Length of header in 8-octet units, excluding first unit.
len: count;
## The TLV encoded options;
options: vector of ip6_option;
options: ip6_options;
};
## Values extracted from an IPv6 Routing extension header.
@ -1245,6 +1248,9 @@ type ip6_ext_hdr: record {
mobility: ip6_mobility_hdr &optional;
};
## A type alias for a vector of IPv6 extension headers
type ip6_ext_hdr_chain: vector of ip6_ext_hdr;
## Values extracted from an IPv6 header.
##
## .. bro:see:: pkt_hdr ip4_hdr ip6_ext_hdr ip6_hopopts ip6_dstopts
@ -1259,7 +1265,7 @@ type ip6_hdr: record {
hlim: count; ##< Hop limit.
src: addr; ##< Source address.
dst: addr; ##< Destination address.
exts: vector of ip6_ext_hdr; ##< Extension header chain.
exts: ip6_ext_hdr_chain; ##< Extension header chain.
};
## Values extracted from an IPv4 header.

View file

@ -36,13 +36,12 @@ static inline RecordType* hdrType(RecordType*& type, const char* name)
static VectorVal* BuildOptionsVal(const u_char* data, int len)
{
VectorVal* vv = new VectorVal(new VectorType(
hdrType(ip6_option_type, "ip6_option")->Ref()));
VectorVal* vv = new VectorVal(internal_type("ip6_options")->AsVectorType());
while ( len > 0 )
{
const struct ip6_opt* opt = (const struct ip6_opt*) data;
RecordVal* rv = new RecordVal(ip6_option_type);
RecordVal* rv = new RecordVal(hdrType(ip6_option_type, "ip6_option"));
rv->Assign(0, new Val(opt->ip6o_type, TYPE_COUNT));
if ( opt->ip6o_type == 0 )
@ -87,8 +86,8 @@ RecordVal* IPv6_Hdr::BuildRecordVal(VectorVal* chain) const
rv->Assign(5, new AddrVal(IPAddr(ip6->ip6_src)));
rv->Assign(6, new AddrVal(IPAddr(ip6->ip6_dst)));
if ( ! chain )
chain = new VectorVal(new VectorType(
hdrType(ip6_ext_hdr_type, "ip6_ext_hdr")->Ref()));
chain = new VectorVal(
internal_type("ip6_ext_hdr_chain")->AsVectorType());
rv->Assign(7, chain);
}
break;
@ -583,7 +582,8 @@ VectorVal* IPv6_Hdr_Chain::BuildVal() const
ip6_mob_type = internal_type("ip6_mobility_hdr")->AsRecordType();
}
VectorVal* rval = new VectorVal(new VectorType(ip6_ext_hdr_type->Ref()));
VectorVal* rval = new VectorVal(
internal_type("ip6_ext_hdr_chain")->AsVectorType());
for ( size_t i = 1; i < chain.size(); ++i )
{

View file

@ -1494,8 +1494,8 @@ function sort%(v: any, ...%) : any
## .. bro:see:: sort
function order%(v: any, ...%) : index_vec
%{
VectorVal* result_v =
new VectorVal(new VectorType(base_type(TYPE_COUNT)));
VectorVal* result_v = new VectorVal(
internal_type("index_vec")->AsVectorType());
if ( v->Type()->Tag() != TYPE_VECTOR )
{
@ -2331,7 +2331,7 @@ function is_v6_addr%(a: addr%): bool
## Returns: The vector of addresses contained in the routing header data.
function routing0_data_to_addrs%(s: string%): addr_vec
%{
VectorVal* rval = new VectorVal(new VectorType(base_type(TYPE_ADDR)));
VectorVal* rval = new VectorVal(internal_type("addr_vec")->AsVectorType());
int len = s->Len();
const u_char* bytes = s->Bytes();
@ -2362,7 +2362,7 @@ function routing0_data_to_addrs%(s: string%): addr_vec
## .. bro:see:: counts_to_addr
function addr_to_counts%(a: addr%): index_vec
%{
VectorVal* rval = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
VectorVal* rval = new VectorVal(internal_type("index_vec")->AsVectorType());
const uint32* bytes;
int len = a->AsAddr().GetBytes(&bytes);

View file

@ -875,8 +875,8 @@ function str_split%(s: string, idx: index_vec%): string_vec
indices[i] = (*idx_v)[i]->AsCount();
BroString::Vec* result = s->AsString()->Split(indices);
VectorVal* result_v =
new VectorVal(new VectorType(base_type(TYPE_STRING)));
VectorVal* result_v = new VectorVal(
internal_type("string_vec")->AsVectorType());
if ( result )
{

View file

@ -0,0 +1,4 @@
weird routing0_hdr from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:78:1:32::2
[orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=53/udp, resp_h=2001:78:1:32::2, resp_p=53/udp]
[ip=<uninitialized>, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=<uninitialized>, routing=<uninitialized>, fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>, mobility=<uninitialized>], [id=43, hopopts=<uninitialized>, dstopts=<uninitialized>, routing=[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>, mobility=<uninitialized>]]], tcp=<uninitialized>, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=<uninitialized>]
[2001:78:1:32::1, 2001:78:1:32::2]

View file

@ -0,0 +1,10 @@
[1, 3, 0, 2]
[2374950123]
[1, 3, 0, 2]
[2374950123]
[1, 3, 0, 2]
[2374950123]
[1, 3, 0, 2]
[3353991673]
[1, 3, 0, 2]
[3353991673]

View file

@ -0,0 +1,37 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/ipv6-hbh-routing0.trace %INPUT >output
# @TEST-EXEC: btest-diff output
# Just check that the event is raised correctly for a packet containing
# extension headers.
event ipv6_ext_headers(c: connection, p: pkt_hdr)
{
print p;
}
# Also check the weird for routing type 0 extensions headers
event flow_weird(name: string, src: addr, dst: addr)
{
print fmt("weird %s from %s to %s", name, src, dst);
}
# And the connection for routing type 0 packets with non-zero segments left
# should use the last address in that extension header.
event new_connection(c: connection)
{
print c$id;
}
event ipv6_ext_headers(c: connection, p: pkt_hdr)
{
for ( h in p$ip6$exts )
if ( p$ip6$exts[h]$id == IPPROTO_ROUTING )
if ( p$ip6$exts[h]$routing$rtype == 0 )
print routing0_data_to_addrs(p$ip6$exts[h]$routing$data);
}

View file

@ -0,0 +1,28 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks
#
# The BIFS used in this test originally didn't call the VectorVal() ctor right,
# assuming that it didn't automatically Ref the VectorType argument and thus
# leaked that memeory.
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m -b -r $TRACES/ftp-ipv4.trace %INPUT >output
# @TEST-EXEC: btest-diff output
function myfunc(aa: interval, bb: interval): int
{
if ( aa < bb )
return -1;
else
return 1;
}
event new_connection(c: connection)
{
local a = vector( 5, 2, 8, 3 );
print order(a);
str_split("this is a test string", a);
print addr_to_counts(c$id$orig_h);
}