diff --git a/CHANGES b/CHANGES index 74da6ab39e..e4a4789f80 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,30 @@ +2.1-1154 | 2013-08-30 08:27:45 -0700 + + * Fix global opaque val segfault. Addresses BIT-1071. (Jon Siwek) + + * Fix malloc/delete mismatch. (Jon Siwek) + + * Fix invalid pointer dereference in AsciiFormatter. (Jon Siwek) + +2.1-1150 | 2013-08-29 13:43:01 -0700 + + * Fix input framework memory leaks. (Jon Siwek) + + * Fix memory leak in SOCKS analyzer for bad addr types. (Jon Siwek) + + * Fix Bloom filter memory leaks. (Jon Siwek) + +2.1-1144 | 2013-08-28 18:51:06 -0700 + + * Add bits_per_uid unit test. Addresses BIT-1016. (Jon Siwek) + + * UID optimizations. Addresses BIT-1016. (Jon Siwek) + + * Added a $unique_max field to Reducers for the SumStats::UNIQUE + calculation, and using the new option in scan.bro and the FTP + bruteforce detection. (Seth Hall) + 2.1-1137 | 2013-08-27 13:26:44 -0700 * Add BiF hexstr_to_bytestring() that does exactly the opposite of diff --git a/VERSION b/VERSION index 1b6b465552..7da5601ca6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1-1137 +2.1-1154 diff --git a/aux/btest b/aux/btest index 35bb074c1c..738bcc72de 160000 --- a/aux/btest +++ b/aux/btest @@ -1 +1 @@ -Subproject commit 35bb074c1c5173e44689df680a24ba13fea39a11 +Subproject commit 738bcc72de0b0a9a4c3359de8328e9c48f3526ef diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 4ec4685b19..fe3b84a93b 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3081,6 +3081,7 @@ const global_hash_seed: string = "" &redef; ## Number of bits in UIDs that are generated to identify connections and ## files. The larger the value, the more confidence in UID uniqueness. +## The maximum is currently 128 bits. const bits_per_uid: count = 96 &redef; # Load BiFs defined by plugins. diff --git a/src/Conn.cc b/src/Conn.cc index e653211583..77c854c126 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -378,7 +378,7 @@ RecordVal* Connection::BuildConnVal() conn_val->Assign(8, new StringVal("")); // history if ( ! uid ) - uid = Bro::UID(bits_per_uid); + uid.Set(bits_per_uid); conn_val->Assign(9, new StringVal(uid.Base62("C").c_str())); diff --git a/src/NetVar.cc b/src/NetVar.cc index b33cc1d6da..7a11c3f2d1 100644 --- a/src/NetVar.cc +++ b/src/NetVar.cc @@ -242,14 +242,6 @@ StringVal* global_hash_seed; bro_uint_t bits_per_uid; -OpaqueType* md5_type; -OpaqueType* sha1_type; -OpaqueType* sha256_type; -OpaqueType* entropy_type; -OpaqueType* cardinality_type; -OpaqueType* topk_type; -OpaqueType* bloomfilter_type; - #include "const.bif.netvar_def" #include "types.bif.netvar_def" #include "event.bif.netvar_def" @@ -313,14 +305,6 @@ void init_general_global_var() global_hash_seed = opt_internal_string("global_hash_seed"); bits_per_uid = opt_internal_unsigned("bits_per_uid"); - - md5_type = new OpaqueType("md5"); - sha1_type = new OpaqueType("sha1"); - sha256_type = new OpaqueType("sha256"); - entropy_type = new OpaqueType("entropy"); - cardinality_type = new OpaqueType("cardinality"); - topk_type = new OpaqueType("topk"); - bloomfilter_type = new OpaqueType("bloomfilter"); } void init_net_var() diff --git a/src/NetVar.h b/src/NetVar.h index 7bb85627b5..c30895d5d4 100644 --- a/src/NetVar.h +++ b/src/NetVar.h @@ -246,15 +246,6 @@ extern StringVal* global_hash_seed; extern bro_uint_t bits_per_uid; -class OpaqueType; -extern OpaqueType* md5_type; -extern OpaqueType* sha1_type; -extern OpaqueType* sha256_type; -extern OpaqueType* entropy_type; -extern OpaqueType* cardinality_type; -extern OpaqueType* topk_type; -extern OpaqueType* bloomfilter_type; - // Initializes globals that don't pertain to network/event analysis. extern void init_general_global_var(); diff --git a/src/TunnelEncapsulation.cc b/src/TunnelEncapsulation.cc index 6330236dc2..cb4b1eaabe 100644 --- a/src/TunnelEncapsulation.cc +++ b/src/TunnelEncapsulation.cc @@ -11,7 +11,7 @@ EncapsulatingConn::EncapsulatingConn(Connection* c, BifEnum::Tunnel::Type t) { if ( ! uid ) { - uid = Bro::UID(bits_per_uid); + uid.Set(bits_per_uid); c->SetUID(uid); } } diff --git a/src/Type.h b/src/Type.h index b10e249745..a6163d5152 100644 --- a/src/Type.h +++ b/src/Type.h @@ -609,6 +609,14 @@ protected: BroType* yield_type; }; +extern OpaqueType* md5_type; +extern OpaqueType* sha1_type; +extern OpaqueType* sha256_type; +extern OpaqueType* entropy_type; +extern OpaqueType* cardinality_type; +extern OpaqueType* topk_type; +extern OpaqueType* bloomfilter_type; + // Returns the BRO basic (non-parameterized) type with the given type. extern BroType* base_type(TypeTag tag); diff --git a/src/UID.cc b/src/UID.cc index b7e5d0617c..28675c0376 100644 --- a/src/UID.cc +++ b/src/UID.cc @@ -7,39 +7,30 @@ using namespace Bro; using namespace std; -void UID::Set(bro_uint_t bits, const std::vector& v) +void UID::Set(bro_uint_t bits, const uint64* v, size_t n) { - uid.clear(); + initialized = true; + + for ( size_t i = 0; i < BRO_UID_LEN; ++i ) + uid[i] = 0; + + if ( bits > BRO_UID_LEN * 64 ) + bits = BRO_UID_LEN * 64; div_t res = div(bits, 64); size_t size = res.rem ? res.quot + 1 : res.quot; for ( size_t i = 0; i < size; ++i ) - uid.push_back(i < v.size() ? v[i] : calculate_unique_id()); + uid[i] = v && i < n ? v[i] : calculate_unique_id(); if ( res.rem ) uid[0] >>= 64 - res.rem; } -string UID::Base62(const std::string& prefix) const - { - char tmp[64]; // technically, this should dynamically scale based on size - string rval(prefix); - - for ( size_t i = 0; i < uid.size(); ++i ) - rval.append(uitoa_n(uid[i], tmp, sizeof(tmp), 62)); - - return rval; - } - bool Bro::operator==(const UID& u1, const UID& u2) { - if ( u1.uid.size() != u2.uid.size() ) - return false; - - for ( size_t i = 0; i < u1.uid.size(); ++i ) + for ( size_t i = 0; i < BRO_UID_LEN; ++i ) if ( u1.uid[i] != u2.uid[i] ) return false; - return true; } diff --git a/src/UID.h b/src/UID.h index a9a77dcc90..9ccf0ae0e8 100644 --- a/src/UID.h +++ b/src/UID.h @@ -4,10 +4,12 @@ #define BRO_UID_H #include -#include +#include "Reporter.h" #include "util.h" +#define BRO_UID_LEN 2 + namespace Bro { /** @@ -18,53 +20,54 @@ class UID { public: /** - * Default ctor. The UID is uninitialized and in string format is - * represented by an empty string. + * Default ctor. The UID is uninitialized. */ - UID() {} + UID() : initialized(false) {} /** * Construct a UID of a given bit-length, optionally from given values. * @see UID::Set */ - UID(bro_uint_t bits, const std::vector& v = std::vector()) - { Set(bits, v); } + UID(bro_uint_t bits, const uint64* v = 0, size_t n = 0) + { Set(bits, v, n); } /** * Copy constructor. */ - UID(const UID& other) { uid = other.uid; } + UID(const UID& other); /** * Inititialize a UID of a given bit-length, optionally from given values. - * @param bits The desired length in bits of the UID. - * @param v A vector of values with which to initialize the UID. - * If empty or doesn't contain enough values to satisfy \a bits, - * then values are automatically generated using + * @param bits The desired length in bits of the UID, up to a max of + * BRO_UID_LEN * 64. + * @param v A pointer to an array of values with which to initialize the + * UID. If empty or doesn't contain enough values to satisfy + * \a bits, then values are automatically generated using * calculate_unique_id(). If \a bits isn't evenly divisible by * 64, then a value is truncated to bit in desired bit-length. + * @param n number of 64-bit elements in array pointed to by \a v. */ - void Set(bro_uint_t bits, - const std::vector& v = std::vector()); + void Set(bro_uint_t bits, const uint64* v = 0, size_t n = 0); /** * Returns a base62 (characters 0-9, A-Z, a-z) representation of the UID. * @param prefix An optional string prefix. * @return a base62 string representing the UID. */ - std::string Base62(const std::string& prefix = "") const; + std::string Base62(std::string prefix = "") const; /** * @return false if the UID instance was created via the default ctor * and not yet initialized w/ Set(). * TODO: this would be better as an "explicit" conversion operator (C++11) */ - operator bool() const { return ( ! uid.empty() ); } + operator bool() const + { return initialized; } /** * Assignment operator. */ - UID& operator=(const UID& other) { uid = other.uid; return *this; } + UID& operator=(const UID& other); /** * UID equality operator. @@ -78,11 +81,41 @@ public: { return ! ( u1 == u2 ); } private: - std::vector uid; + uint64 uid[BRO_UID_LEN]; + bool initialized; // Since technically uid == 0 is a legit UID }; bool operator==(const UID& u1, const UID& u2); +inline UID::UID(const UID& other) + { + for ( size_t i = 0; i < BRO_UID_LEN; ++i ) + uid[i] = other.uid[i]; + + initialized = other.initialized; + } + +inline UID& UID::operator=(const UID& other) + { + for ( size_t i = 0; i < BRO_UID_LEN; ++i ) + uid[i] = other.uid[i]; + + initialized = other.initialized; + return *this; + } + +inline std::string UID::Base62(std::string prefix) const + { + if ( ! initialized ) + reporter->InternalError("use of uninitialized UID"); + + char tmp[64]; // technically, this should dynamically scale w/ BRO_UID_LEN + for ( size_t i = 0; i < BRO_UID_LEN; ++i ) + prefix.append(uitoa_n(uid[i], tmp, sizeof(tmp), 62)); + + return prefix; + } + } // namespace Bro #endif diff --git a/src/analyzer/protocol/socks/socks-analyzer.pac b/src/analyzer/protocol/socks/socks-analyzer.pac index 80051f0b27..885542fc2a 100644 --- a/src/analyzer/protocol/socks/socks-analyzer.pac +++ b/src/analyzer/protocol/socks/socks-analyzer.pac @@ -85,8 +85,8 @@ refine connection SOCKS_Conn += { default: bro_analyzer()->ProtocolViolation(fmt("invalid SOCKSv5 addr type: %d", ${request.remote_name.addr_type})); + Unref(sa); return false; - break; } BifEvent::generate_socks_request(bro_analyzer(), @@ -124,8 +124,8 @@ refine connection SOCKS_Conn += { default: bro_analyzer()->ProtocolViolation(fmt("invalid SOCKSv5 addr type: %d", ${reply.bound.addr_type})); + Unref(sa); return false; - break; } BifEvent::generate_socks_reply(bro_analyzer(), diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 77441f8264..8dfb220381 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -64,10 +64,7 @@ string Manager::HashHandle(const string& handle) const MD5(reinterpret_cast(msg.data()), msg.size(), reinterpret_cast(hash)); - vector v; - v.push_back(hash[0]); - v.push_back(hash[1]); - return Bro::UID(bits_per_uid, v).Base62("F"); + return Bro::UID(bits_per_uid, hash, 2).Base62("F"); } void Manager::SetHandle(const string& handle) diff --git a/src/input/Manager.cc b/src/input/Manager.cc index d467e32005..2534ed1b69 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -74,7 +74,6 @@ declare(PDict, InputHash); class Manager::Stream { public: string name; - ReaderBackend::ReaderInfo* info; bool removed; StreamType stream_type; // to distinguish between event and table streams @@ -318,23 +317,23 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) string source((const char*) bsource->Bytes(), bsource->Len()); Unref(sourceval); - ReaderBackend::ReaderInfo* rinfo = new ReaderBackend::ReaderInfo(); - rinfo->source = copy_string(source.c_str()); - rinfo->name = copy_string(name.c_str()); + ReaderBackend::ReaderInfo rinfo; + rinfo.source = copy_string(source.c_str()); + rinfo.name = copy_string(name.c_str()); EnumVal* mode = description->LookupWithDefault(rtype->FieldOffset("mode"))->AsEnumVal(); switch ( mode->InternalInt() ) { case 0: - rinfo->mode = MODE_MANUAL; + rinfo.mode = MODE_MANUAL; break; case 1: - rinfo->mode = MODE_REREAD; + rinfo.mode = MODE_REREAD; break; case 2: - rinfo->mode = MODE_STREAM; + rinfo.mode = MODE_STREAM; break; default: @@ -357,7 +356,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) ListVal* index = info->config->RecoverIndex(k); string key = index->Index(0)->AsString()->CheckString(); string value = v->Value()->AsString()->CheckString(); - rinfo->config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str()))); + rinfo.config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str()))); Unref(index); delete k; } @@ -365,13 +364,12 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) } - ReaderFrontend* reader_obj = new ReaderFrontend(*rinfo, reader); + ReaderFrontend* reader_obj = new ReaderFrontend(rinfo, reader); assert(reader_obj); info->reader = reader_obj; info->type = reader->AsEnumVal(); // ref'd by lookupwithdefault info->name = name; - info->info = rinfo; Ref(description); info->description = description; @@ -1356,7 +1354,8 @@ void Manager::SendEndOfData(const Stream *i) DBG_LOG(DBG_INPUT, "SendEndOfData for stream %s", i->name.c_str()); #endif - SendEvent(end_of_data, 2, new StringVal(i->name.c_str()), new StringVal(i->info->source)); + SendEvent(end_of_data, 2, new StringVal(i->name.c_str()), + new StringVal(i->reader->Info().source)); if ( i->stream_type == ANALYSIS_STREAM ) file_mgr->EndOfFile(static_cast(i)->file_id); @@ -2091,9 +2090,7 @@ HashKey* Manager::HashValues(const int num_elements, const Value* const *vals) return NULL; int position = 0; - char *data = (char*) malloc(length); - if ( data == 0 ) - reporter->InternalError("Could not malloc?"); + char *data = new char[length]; for ( int i = 0; i < num_elements; i++ ) { @@ -2109,7 +2106,7 @@ HashKey* Manager::HashValues(const int num_elements, const Value* const *vals) } HashKey *key = new HashKey(data, length); - delete data; + delete [] data; assert(position == length); return key; diff --git a/src/input/ReaderBackend.h b/src/input/ReaderBackend.h index 5419879e13..84984a3ce5 100644 --- a/src/input/ReaderBackend.h +++ b/src/input/ReaderBackend.h @@ -121,6 +121,7 @@ public: ~ReaderInfo() { delete [] source; + delete [] name; for ( config_map::iterator i = config.begin(); i != config.end(); i++ ) { diff --git a/src/main.cc b/src/main.cc index 9868f62be9..5acba12367 100644 --- a/src/main.cc +++ b/src/main.cc @@ -124,6 +124,14 @@ vector params; char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value +OpaqueType* md5_type = 0; +OpaqueType* sha1_type = 0; +OpaqueType* sha256_type = 0; +OpaqueType* entropy_type = 0; +OpaqueType* cardinality_type = 0; +OpaqueType* topk_type = 0; +OpaqueType* bloomfilter_type = 0; + extern std::list docs_generated; // Keep copy of command line @@ -845,6 +853,14 @@ int main(int argc, char** argv) input::reader::Raw::ClassInit(); + md5_type = new OpaqueType("md5"); + sha1_type = new OpaqueType("sha1"); + sha256_type = new OpaqueType("sha256"); + entropy_type = new OpaqueType("entropy"); + cardinality_type = new OpaqueType("cardinality"); + topk_type = new OpaqueType("topk"); + bloomfilter_type = new OpaqueType("bloomfilter"); + // The leak-checker tends to produce some false // positives (memory which had already been // allocated before we start the checking is diff --git a/src/probabilistic/BloomFilter.cc b/src/probabilistic/BloomFilter.cc index 4d5c5171ec..f6e4017626 100644 --- a/src/probabilistic/BloomFilter.cc +++ b/src/probabilistic/BloomFilter.cc @@ -125,6 +125,11 @@ BasicBloomFilter::BasicBloomFilter(const Hasher* hasher, size_t cells) bits = new BitVector(cells); } +BasicBloomFilter::~BasicBloomFilter() + { + delete bits; + } + IMPLEMENT_SERIAL(BasicBloomFilter, SER_BASICBLOOMFILTER) bool BasicBloomFilter::DoSerialize(SerialInfo* info) const @@ -173,6 +178,11 @@ CountingBloomFilter::CountingBloomFilter(const Hasher* hasher, cells = new CounterVector(width, arg_cells); } +CountingBloomFilter::~CountingBloomFilter() + { + delete cells; + } + bool CountingBloomFilter::Empty() const { return cells->AllZero(); diff --git a/src/probabilistic/BloomFilter.h b/src/probabilistic/BloomFilter.h index 65dda2396d..53b66c377e 100644 --- a/src/probabilistic/BloomFilter.h +++ b/src/probabilistic/BloomFilter.h @@ -124,6 +124,11 @@ public: */ BasicBloomFilter(const Hasher* hasher, size_t cells); + /** + * Destructor. + */ + ~BasicBloomFilter(); + /** * Computes the number of cells based on a given false positive rate * and capacity. In the literature, this parameter often has the name @@ -192,6 +197,11 @@ public: */ CountingBloomFilter(const Hasher* hasher, size_t cells, size_t width); + /** + * Destructor. + */ + ~CountingBloomFilter(); + // Overridden from BloomFilter. virtual bool Empty() const; virtual void Clear(); diff --git a/src/threading/AsciiFormatter.cc b/src/threading/AsciiFormatter.cc index cb1c57f6f1..616abbe2b6 100644 --- a/src/threading/AsciiFormatter.cc +++ b/src/threading/AsciiFormatter.cc @@ -247,7 +247,8 @@ threading::Value* AsciiFormatter::ParseValue(string s, string name, TypeTag type goto parse_error; } - uint8_t width = (uint8_t) strtol(s.substr(pos+1).c_str(), &end, 10); + string width_str = s.substr(pos + 1); + uint8_t width = (uint8_t) strtol(width_str.c_str(), &end, 10); if ( CheckNumberError(s, end) ) goto parse_error; diff --git a/testing/btest/Baseline/core.bits_per_uid/128 b/testing/btest/Baseline/core.bits_per_uid/128 new file mode 100644 index 0000000000..95ef343262 --- /dev/null +++ b/testing/btest/Baseline/core.bits_per_uid/128 @@ -0,0 +1,9 @@ +CUWkUyAuUGXfarKYeMETxOg +Ck6kgXLOoSKlnQcgTWjvg4c +Cj4u32Pc5bifTEfuqmmG4bh +Fj3nTWNjezo6G6xBmyo58Tf +F4VAnSiNGSQhKEoCPd4zuQd +CFrJExwHcSal5OKnoww6xl4 +C3PKsZ2Uye21VW0XPVINV8a +FaJg8mtdsS86cWjSe4spPPl +FvBr89nD30GgGAp3wgtm6qf diff --git a/testing/btest/Baseline/core.bits_per_uid/256 b/testing/btest/Baseline/core.bits_per_uid/256 new file mode 100644 index 0000000000..95ef343262 --- /dev/null +++ b/testing/btest/Baseline/core.bits_per_uid/256 @@ -0,0 +1,9 @@ +CUWkUyAuUGXfarKYeMETxOg +Ck6kgXLOoSKlnQcgTWjvg4c +Cj4u32Pc5bifTEfuqmmG4bh +Fj3nTWNjezo6G6xBmyo58Tf +F4VAnSiNGSQhKEoCPd4zuQd +CFrJExwHcSal5OKnoww6xl4 +C3PKsZ2Uye21VW0XPVINV8a +FaJg8mtdsS86cWjSe4spPPl +FvBr89nD30GgGAp3wgtm6qf diff --git a/testing/btest/Baseline/core.bits_per_uid/32 b/testing/btest/Baseline/core.bits_per_uid/32 new file mode 100644 index 0000000000..a20d05dbd5 --- /dev/null +++ b/testing/btest/Baseline/core.bits_per_uid/32 @@ -0,0 +1,9 @@ +CXWv6p30 +CCyvnA30 +CjhGID40 +F75yAm10 +FmGk6O30 +CdfHBz20 +CCvvfg30 +Fuh3fj10 +Ftwuyy30 diff --git a/testing/btest/Baseline/core.bits_per_uid/64 b/testing/btest/Baseline/core.bits_per_uid/64 new file mode 100644 index 0000000000..b34eb4879d --- /dev/null +++ b/testing/btest/Baseline/core.bits_per_uid/64 @@ -0,0 +1,9 @@ +CUWkUyAuUGXf0 +CarKYeMETxOg0 +Ck6kgXLOoSKl0 +Fj3nTWNjezo60 +F4VAnSiNGSQh0 +CnQcgTWjvg4c0 +Cj4u32Pc5bif0 +FaJg8mtdsS860 +FvBr89nD30Gg0 diff --git a/testing/btest/Baseline/core.bits_per_uid/96 b/testing/btest/Baseline/core.bits_per_uid/96 new file mode 100644 index 0000000000..3ba0f50e04 --- /dev/null +++ b/testing/btest/Baseline/core.bits_per_uid/96 @@ -0,0 +1,9 @@ +CXWv6p3arKYeMETxOg +CjhGID4nQcgTWjvg4c +CCvvfg3TEfuqmmG4bh +F75yAm1G6xBmyo58Tf +FmGk6O3KEoCPd4zuQd +CsRx2w45OKnoww6xl4 +CRJuHdVW0XPVINV8a +Fuh3fj1cWjSe4spPPl +Ftwuyy3GAp3wgtm6qf diff --git a/testing/btest/Baseline/core.global_opaque_val/output b/testing/btest/Baseline/core.global_opaque_val/output new file mode 100644 index 0000000000..db604ebbf4 --- /dev/null +++ b/testing/btest/Baseline/core.global_opaque_val/output @@ -0,0 +1 @@ +7b0391feb2e0cd271f1cf39aafb4376f diff --git a/testing/btest/core/bits_per_uid.bro b/testing/btest/core/bits_per_uid.bro new file mode 100644 index 0000000000..6e997907de --- /dev/null +++ b/testing/btest/core/bits_per_uid.bro @@ -0,0 +1,21 @@ +# @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT bits_per_uid=32 >32 +# @TEST-EXEC: btest-diff 32 +# @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT bits_per_uid=64 >64 +# @TEST-EXEC: btest-diff 64 +# @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT bits_per_uid=96 >96 +# @TEST-EXEC: btest-diff 96 +# @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT bits_per_uid=128 >128 +# @TEST-EXEC: btest-diff 128 +# @TEST-EXEC: bro -r $TRACES/ftp/ipv4.trace %INPUT bits_per_uid=256 >256 +# @TEST-EXEC: btest-diff 256 +# @TEST-EXEC: cmp 128 256 + +event new_connection(c: connection) + { + print c$uid; + } + +event file_new(f: fa_file) + { + print f$id; + } diff --git a/testing/btest/core/global_opaque_val.bro b/testing/btest/core/global_opaque_val.bro new file mode 100644 index 0000000000..84087d8295 --- /dev/null +++ b/testing/btest/core/global_opaque_val.bro @@ -0,0 +1,12 @@ +# @TEST-EXEC: bro -b %INPUT >output +# @TEST-EXEC: btest-diff output + +global test = md5_hash_init(); + +event bro_init() + { + md5_hash_update(test, "one"); + md5_hash_update(test, "two"); + md5_hash_update(test, "three"); + print md5_hash_finish(test); + } diff --git a/testing/btest/core/leaks/bloomfilter.bro b/testing/btest/core/leaks/bloomfilter.bro new file mode 100644 index 0000000000..6d9b74114e --- /dev/null +++ b/testing/btest/core/leaks/bloomfilter.bro @@ -0,0 +1,101 @@ +# Needs perftools support. +# +# @TEST-GROUP: leaks +# +# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks +# +# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -m -b -r $TRACES/wikipedia.trace %INPUT +# @TEST-EXEC: btest-bg-wait 15 + +function test_basic_bloom_filter() + { + # Basic usage with counts. + local bf_cnt = bloomfilter_basic_init(0.1, 1000); + bloomfilter_add(bf_cnt, 42); + bloomfilter_add(bf_cnt, 84); + bloomfilter_add(bf_cnt, 168); + print bloomfilter_lookup(bf_cnt, 0); + print bloomfilter_lookup(bf_cnt, 42); + print bloomfilter_lookup(bf_cnt, 168); + print bloomfilter_lookup(bf_cnt, 336); + bloomfilter_add(bf_cnt, 0.5); # Type mismatch + bloomfilter_add(bf_cnt, "foo"); # Type mismatch + + # Alternative constructor. + local bf_dbl = bloomfilter_basic_init2(4, 10); + bloomfilter_add(bf_dbl, 4.2); + bloomfilter_add(bf_dbl, 3.14); + print bloomfilter_lookup(bf_dbl, 4.2); + print bloomfilter_lookup(bf_dbl, 3.14); + + # Basic usage with strings. + local bf_str = bloomfilter_basic_init(0.9, 10); + bloomfilter_add(bf_str, "foo"); + bloomfilter_add(bf_str, "bar"); + print bloomfilter_lookup(bf_str, "foo"); + print bloomfilter_lookup(bf_str, "bar"); + print bloomfilter_lookup(bf_str, "bazzz"), "fp"; # FP + print bloomfilter_lookup(bf_str, "quuux"), "fp"; # FP + bloomfilter_add(bf_str, 0.5); # Type mismatch + bloomfilter_add(bf_str, 100); # Type mismatch + + # Edge cases. + local bf_edge0 = bloomfilter_basic_init(0.000000000001, 1); + local bf_edge1 = bloomfilter_basic_init(0.00000001, 100000000); + local bf_edge2 = bloomfilter_basic_init(0.9999999, 1); + local bf_edge3 = bloomfilter_basic_init(0.9999999, 100000000000); + + # Invalid parameters. + local bf_bug0 = bloomfilter_basic_init(-0.5, 42); + local bf_bug1 = bloomfilter_basic_init(1.1, 42); + + # Merging + local bf_cnt2 = bloomfilter_basic_init(0.1, 1000); + bloomfilter_add(bf_cnt2, 42); + bloomfilter_add(bf_cnt, 100); + local bf_merged = bloomfilter_merge(bf_cnt, bf_cnt2); + print bloomfilter_lookup(bf_merged, 42); + print bloomfilter_lookup(bf_merged, 84); + print bloomfilter_lookup(bf_merged, 100); + print bloomfilter_lookup(bf_merged, 168); + + #empty filter tests + local bf_empty = bloomfilter_basic_init(0.1, 1000); + local bf_empty_merged = bloomfilter_merge(bf_merged, bf_empty); + print bloomfilter_lookup(bf_empty_merged, 42); + } + +function test_counting_bloom_filter() + { + local bf = bloomfilter_counting_init(3, 32, 3); + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 1 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 2 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # 3 + bloomfilter_add(bf, "foo"); + print bloomfilter_lookup(bf, "foo"); # still 3 + + + bloomfilter_add(bf, "bar"); + bloomfilter_add(bf, "bar"); + print bloomfilter_lookup(bf, "bar"); # 2 + print bloomfilter_lookup(bf, "foo"); # still 3 + + # Merging + local bf2 = bloomfilter_counting_init(3, 32, 3); + bloomfilter_add(bf2, "baz"); + bloomfilter_add(bf2, "baz"); + bloomfilter_add(bf2, "bar"); + local bf_merged = bloomfilter_merge(bf, bf2); + print bloomfilter_lookup(bf_merged, "foo"); + print bloomfilter_lookup(bf_merged, "bar"); + print bloomfilter_lookup(bf_merged, "baz"); + } + +event new_connection(c: connection) + { + test_basic_bloom_filter(); + test_counting_bloom_filter(); + }