Merge remote-tracking branch 'origin/topic/jsiwek/asan'

* origin/topic/jsiwek/asan: (28 commits)
  Increase timeout for a btest
  Switch CI scripts to use ASAN/LSAN instead of gperftools
  Remove redundant memory leak btests
  Fix reference counting issues related to lambdas/closures
  Disable LeakSanitizer for btests that have known leaks
  Rewrite the btest for when-statement timeouts
  Fix memory leak when a logging plugin hook prevents a write
  Fix memory leaks in various input framework error-handling cases
  Fix memory leak in Reporter::get_weird_sampling_whitelist() BIF
  Fix reference counting of Log::Filter "config" field
  Fix memory leak in system_env() BIF
  Clean up triggers awaiting global state modification at shutdown
  Fix memory leak in initializing log writers with no local backend
  Fix packet filter memory leaks
  Skip sending thread heartbeat if it alread asked to be finished
  Fix memory leak of sqlite input reader prepared statement
  Prevent duplicate "finish" threading messages
  Fix memory leak when table-based input stream overwrites old entries
  Fix scripting error in a DHCP btest
  Fix memory leaks in Kerberos ticket decryption
  ...
This commit is contained in:
Tim Wojtulewicz 2020-01-06 11:19:36 -07:00
commit 65a4e36a92
170 changed files with 1014 additions and 4827 deletions

View file

@ -3,7 +3,7 @@ btest_jobs: &BTEST_JOBS 8
memory: &MEMORY 8GB memory: &MEMORY 8GB
config: &CONFIG --build-type=release --enable-cpp-tests config: &CONFIG --build-type=release --enable-cpp-tests
leak_config: &LEAK_CONFIG --build-type=debug --enable-perftools-debug memcheck_config: &MEMCHECK_CONFIG --build-type=debug --enable-cpp-tests --sanitizers=address
resources_template: &RESOURCES_TEMPLATE resources_template: &RESOURCES_TEMPLATE
cpu: *CPUS cpu: *CPUS
@ -16,8 +16,7 @@ ci_template: &CI_TEMPLATE
$CIRRUS_BRANCH =~ 'release/.*' $CIRRUS_BRANCH =~ 'release/.*'
# Default timeout is 60 minutes, Cirrus hard limit is 120 minutes for free # Default timeout is 60 minutes, Cirrus hard limit is 120 minutes for free
# tasks. This leakcheck one can tend to run long, but see no downside # tasks, so may as well ask for full time.
# to universally asking for the maximum.
timeout_in: 120m timeout_in: 120m
sync_submodules_script: git submodule update --recursive --init sync_submodules_script: git submodule update --recursive --init
@ -114,13 +113,11 @@ freebsd_task:
prepare_script: ./ci/freebsd/prepare.sh prepare_script: ./ci/freebsd/prepare.sh
<< : *CI_TEMPLATE << : *CI_TEMPLATE
leakcheck_task: memcheck_task:
container: container:
# Just uses a recent/common distro to run leak checks. # Just uses a recent/common distro to run memory error/leak checks.
dockerfile: ci/ubuntu-18.04/Dockerfile dockerfile: ci/ubuntu-18.04/Dockerfile
<< : *RESOURCES_TEMPLATE << : *RESOURCES_TEMPLATE
<< : *CI_TEMPLATE << : *CI_TEMPLATE
env: env:
ZEEK_CI_LEAK_CHECK: true ZEEK_CI_CONFIGURE_FLAGS: *MEMCHECK_CONFIG
ZEEK_CI_CONFIGURE_FLAGS: *LEAK_CONFIG
ZEEK_CI_BTEST_JOBS: 7

138
CHANGES
View file

@ -1,4 +1,142 @@
3.1.0-dev.348 | 2020-01-06 11:19:36 -0700
* Increase timeout for a btest
May be more timing-sensitive with slower ASAN/LSAN configuration in
addition to already-slower CI environment. (Jon Siwek, Corelight)
* Switch CI scripts to use ASAN/LSAN instead of gperftools
Using AddressSanitizer/LeakSanitizer is better. It covers the full
unit/baseline test suite by default without requiring one to write
specific memory leak tests. It also covers other types of memory errors
besides just leaks. (Jon Siwek, Corelight)
* Remove redundant memory leak btests
Or otherwise convert into a regular btest if it didn't already seem to
be covered.
There's no need for a separate memory leak test group since compiling
with LeakSanitizer now covers leak checking for the full btest suite. (Jon Siwek, Corelight)
* Fix reference counting issues related to lambdas/closures
For example, circular references between a lambda function the frame
it's stored within and/or its closure could cause memory leaks.
This also fixes other various reference-count ownership issues that
could lead to memory errors.
There may still be some potential/undiscovered issues because the "outer
ID" finding logic doesn't look quite right as the AST traversal descends
within nested lambdas and considers their locals as "outer", but
possibly the other logic for locating values in closures or cloning
closures just works around that behavior. (Jon Siwek, Corelight)
* Disable LeakSanitizer for btests that have known leaks
E.g. ones that throw interpreter exceptions, as those are currently
known to potentially cause leaks. Fixing the underlying leaks involves
the larger task of more IntrusivePtr usage.
Reference cycles may also cause leaks. (Jon Siwek, Corelight)
* Rewrite the btest for when-statement timeouts
To avoid a memory leak in DNS lookups that's hard to work around and
does not otherwise effect typical operation when Zeek is allowed to
continue to run after zeek_init(). (Jon Siwek, Corelight)
* Fix memory leak when a logging plugin hook prevents a write (Jon Siwek, Corelight)
* Fix memory leaks in various input framework error-handling cases (Jon Siwek, Corelight)
* Fix memory leak in Reporter::get_weird_sampling_whitelist() BIF (Jon Siwek, Corelight)
* Fix reference counting of Log::Filter "config" field
Which can potentially be a minor memory leak if there's a lot of dynamic
adding/removing of logging filters. (Jon Siwek, Corelight)
* Fix memory leak in system_env() BIF (Jon Siwek, Corelight)
* Clean up triggers awaiting global state modification at shutdown
Otherwise they can be reported as memory leaks since no more global
state modifications will take place to notify the trigger to clean
itself up. (Jon Siwek, Corelight)
* Fix memory leak in initializing log writers with no local backend (Jon Siwek, Corelight)
* Fix packet filter memory leaks (Jon Siwek, Corelight)
* Skip sending thread heartbeat if it alread asked to be finished
Otherwise the heartbeat message may fail to be processed and show up as
leaked memory. (Jon Siwek, Corelight)
* Fix memory leak of sqlite input reader prepared statement (Jon Siwek, Corelight)
* Prevent duplicate "finish" threading messages
As they don't get processed and may show up as a memory leak. (Jon Siwek, Corelight)
* Fix memory leak when table-based input stream overwrites old entries (Jon Siwek, Corelight)
* Fix scripting error in a DHCP btest (Jon Siwek, Corelight)
* Fix memory leaks in Kerberos ticket decryption
Memory allocated to the decrypted ticket data as well as the server
principal were not freed.
Also fixed potential leaks in error cases that called
krb5_get_error_message() without freeing the returned value. (Jon Siwek, Corelight)
* Fix scripting error in an ftp btest (Jon Siwek, Corelight)
* Update paraglob submodule (Jon Siwek, Corelight)
* Fix malloc/delete mismatch in JSON formatting
ODesc allocated with malloc() and BroString deallocated with delete[],
but really the intermediate BroString wasn't even needed when copying
into std::string. (Jon Siwek, Corelight)
* Delete/timeout pending DNS requests during shutdown
Primarily, this change prevents the pending requests showing up as
memory leaks. (Jon Siwek, Corelight)
* Fix memory leak in OCSP parsing functions
Various OCSP parsing functions used in presence of OpenSSL 1.1 used
"d2i_ASN1_SEQUENCE_ANY" which returns a "STACK_OF(ASN1_TYPE)", but used
"sk_ASN1_TYPE_free" instead of "sk_ASN1_TYPE_pop_free" to free it. The
former only frees the stack structure while the later frees both the
structure and the elements. (Jon Siwek, Corelight)
* Free the global X509 certificate root store on shutdown
Otherwise LeakSanitizer reports its contents as leaked. (Jon Siwek, Corelight)
* Add general LeakSanitizer macros/instrumentation (Jon Siwek, Corelight)
* Improve --sanitizers configure option
* Rename SANITIZERS CMake variable to ZEEK_SANITIZERS for clarity
* Use -O1 by default to improve speed (set NO_OPTIMIZATIONS env. var.
to override and use -O0). Uses -fno-optimize-sibling-calls with -O1
to still get "perfect stack traces".
* Updates various sub-projects with sanitizer improvements:
binpac and bifcl, by default, now ignore leaks reported by LeakSanitizer
so that it doesn't interfere with the Zeek build (Jon Siwek, Corelight)
3.1.0-dev.319 | 2020-01-06 09:44:11 -0800 3.1.0-dev.319 | 2020-01-06 09:44:11 -0800
* Mark safe_snprintf and safe_vsnprintf as deprecated, remove uses of them (Tim Wojtulewicz, Corelight) * Mark safe_snprintf and safe_vsnprintf as deprecated, remove uses of them (Tim Wojtulewicz, Corelight)

View file

@ -121,10 +121,30 @@ if ( NOT BINARY_PACKAGING_MODE )
_make_install_dir_symlink("${CMAKE_INSTALL_PREFIX}/lib/bro" "${CMAKE_INSTALL_PREFIX}/lib/zeek") _make_install_dir_symlink("${CMAKE_INSTALL_PREFIX}/lib/bro" "${CMAKE_INSTALL_PREFIX}/lib/zeek")
endif () endif ()
if ( SANITIZERS ) if ( ZEEK_SANITIZERS )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${SANITIZERS} -fno-omit-frame-pointer") # Check the thread library info early as setting compiler flags seems to
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=${SANITIZERS} -fno-omit-frame-pointer") # interfere with the detection and cause CMAKE_THREAD_LIBS_INIT to not
set(CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} -fsanitize=${SANITIZERS} -fno-omit-frame-pointer") # include -lpthread when it should.
find_package(Threads)
set(_sanitizer_flags "-fsanitize=${ZEEK_SANITIZERS}")
set(_sanitizer_flags "${_sanitizer_flags} -fno-omit-frame-pointer")
set(_sanitizer_flags "${_sanitizer_flags} -fno-optimize-sibling-calls")
if ( NOT DEFINED ENV{NO_OPTIMIZATIONS} )
# Using -O1 is generally the suggestion to get more reasonable
# performance. The one downside is it that the compiler may optimize out
# code that otherwise generates an error/leak in a -O0 build, but that
# should be rare and users mostly will not be running unoptimized builds
# in production anyway.
set(_sanitizer_flags "${_sanitizer_flags} -O1")
endif ()
# Technically, the we also need to use the compiler to drive linking and
# give the sanitizer flags there, too. However, CMake, by default, uses
# the compiler for linking and so the automatically flags get used. See
# https://cmake.org/pipermail/cmake/2014-August/058268.html
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_sanitizer_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_sanitizer_flags}")
endif() endif()
######################################################################## ########################################################################
@ -205,6 +225,10 @@ if ( BROKER_ROOT_DIR )
set(zeekdeps ${zeekdeps} ${BROKER_LIBRARY}) set(zeekdeps ${zeekdeps} ${BROKER_LIBRARY})
set(broker_includes ${BROKER_INCLUDE_DIR}) set(broker_includes ${BROKER_INCLUDE_DIR})
else () else ()
if ( ZEEK_SANITIZERS )
set(BROKER_SANITIZERS ${ZEEK_SANITIZERS})
endif ()
set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY}) set(ENABLE_STATIC_ONLY_SAVED ${ENABLE_STATIC_ONLY})
if ( BUILD_STATIC_BROKER ) if ( BUILD_STATIC_BROKER )

View file

@ -1 +1 @@
3.1.0-dev.319 3.1.0-dev.348

@ -1 +1 @@
Subproject commit e5b1940850d486e3989f6a55615140a16bd1b9d2 Subproject commit 9cc1f0dfcd7c9d7c7a4031d45732268e0d68206f

@ -1 +1 @@
Subproject commit c02d6ff7be6bcee097d668f4f667f83c82a28cc6 Subproject commit 71f815a22027bef47fa46459a1010013bd4f59e3

@ -1 +1 @@
Subproject commit 237c3cd2d87d467a5b9ac0517c6461ac00c7b85c Subproject commit 5156ba056e1747b31466a29898564065d20d30a1

@ -1 +1 @@
Subproject commit 6c2b36193e47490e61f22ce6de233af7ed3101b1 Subproject commit d65dd0aa04e73cca884d3630b57532bb3fe3974d

View file

@ -2,8 +2,7 @@
# It's possible to use this script locally from the zeek repo's root dir. # It's possible to use this script locally from the zeek repo's root dir.
# The parallelism level when running tests locally is $1 if provided, else # The parallelism level when running tests locally is $1 if provided, else
# the value of `nproc` if available, otherwise just a single core. Run with # the value of `nproc` if available, otherwise just a single core.
# ZEEK_CI_LEAK_CHECK set to do just the leak checks.
result=0 result=0
BTEST=$(pwd)/aux/btest/btest BTEST=$(pwd)/aux/btest/btest
@ -102,57 +101,10 @@ function run_external_btests
fi fi
} }
function run_leak_tests
{
local zeek_testing_pid=""
local zeek_testing_pid_private=""
banner "Running memory leak tests: zeek"
pushd testing/btest
${BTEST} -d -b -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} -g leaks || result=1
prep_artifacts
popd
pushd testing/external/zeek-testing
${BTEST} -d -b -x btest-results.xml -j ${ZEEK_CI_BTEST_JOBS} -g leaks >btest.out 2>&1 &
zeek_testing_pid=$!
popd
if [[ -d testing/external/zeek-testing-private ]]; then
pushd testing/external/zeek-testing-private
# Note that we don't use btest's "-d" flag or generate/upload any
# artifacts to prevent leaking information about the private pcaps.
${BTEST} -b -j ${ZEEK_CI_BTEST_JOBS} -g leaks >btest.out 2>&1 &
zeek_testing_private_pid=$!
popd
fi
banner "Running memory leak tests: external/zeek-testing"
wait ${zeek_testing_pid} || result=1
pushd testing/external/zeek-testing
cat btest.out
prep_artifacts
popd
if [[ -n "${zeek_testing_private_pid}" ]]; then
banner "Running memory leak tests: external/zeek-testing-private"
wait ${zeek_testing_private_pid} || result=1
cat testing/external/zeek-testing-private/btest.out
else
banner "Skipping private tests (not available for PRs)"
fi
return 0
}
banner "Start tests: ${ZEEK_CI_CPUS} cpus, ${ZEEK_CI_BTEST_JOBS} btest jobs" banner "Start tests: ${ZEEK_CI_CPUS} cpus, ${ZEEK_CI_BTEST_JOBS} btest jobs"
if [[ -n "${ZEEK_CI_LEAK_CHECK}" ]]; then run_unit_tests
run_leak_tests run_btests
else run_external_btests
run_unit_tests
run_btests
run_external_btests
fi
exit ${result} exit ${result}

View file

@ -100,7 +100,7 @@ install_in_docker() {
distro_cmds="apt-get update; apt-get -y install wget xz-utils gdb cmake make gcc g++ flex bison python3 libpcap-dev libssl-dev zlib1g-dev libkrb5-dev git sqlite3 curl bsdmainutils; ln -s /usr/bin/python3 /usr/local/bin/python" distro_cmds="apt-get update; apt-get -y install wget xz-utils gdb cmake make gcc g++ flex bison python3 libpcap-dev libssl-dev zlib1g-dev libkrb5-dev git sqlite3 curl bsdmainutils; ln -s /usr/bin/python3 /usr/local/bin/python"
;; ;;
${LEAK_TEST_DISTRO}) ${LEAK_TEST_DISTRO})
distro_cmds="apt-get update; apt-get -y install gdb cmake make gcc g++ flex bison python3 libpcap-dev libssl-dev zlib1g-dev libkrb5-dev git sqlite3 curl bsdmainutils google-perftools libgoogle-perftools4 libgoogle-perftools-dev; ln -s /usr/bin/python3 /usr/local/bin/python" distro_cmds="apt-get update; apt-get -y install gdb cmake make gcc g++ flex bison python3 libpcap-dev libssl-dev zlib1g-dev libkrb5-dev git sqlite3 curl bsdmainutils; ln -s /usr/bin/python3 /usr/local/bin/python"
local_distro="ubuntu_18.04" local_distro="ubuntu_18.04"
;; ;;
*) *)
@ -168,7 +168,7 @@ build() {
./configure --build-type=Release --disable-broker-tests --enable-cpp-tests --disable-python --disable-zeekctl && make -j 2 ./configure --build-type=Release --disable-broker-tests --enable-cpp-tests --disable-python --disable-zeekctl && make -j 2
else else
echo "Configuring zeek to build for leak testing" echo "Configuring zeek to build for leak testing"
./configure --build-type=Debug --disable-broker-tests --disable-python --disable-zeekctl --enable-perftools --enable-perftools-debug && make -j 2 ./configure --build-type=Debug --disable-broker-tests --enable-cpp-tests --disable-python --disable-zeekctl --sanitizers=address && make -j 2
fi fi
} }
@ -209,7 +209,6 @@ run() {
ulimit -a ulimit -a
ret=0 ret=0
if [ "${BUILD_DISTRO}" != "${LEAK_TEST_DISTRO}" ]; then
echo echo
echo "Running unit tests ##################################################" echo "Running unit tests ##################################################"
echo echo
@ -222,7 +221,6 @@ run() {
fi fi
set -e set -e
fi
echo echo
echo "Running baseline tests ##############################################" echo "Running baseline tests ##############################################"
@ -231,11 +229,7 @@ run() {
set +e set +e
# Must specify a value for "-j" option, otherwise Travis uses a huge value. # Must specify a value for "-j" option, otherwise Travis uses a huge value.
if [ "${BUILD_DISTRO}" != "${LEAK_TEST_DISTRO}" ]; then
../../aux/btest/btest -j 4 -d ../../aux/btest/btest -j 4 -d
else
../../aux/btest/btest -j 4 -d -g leaks
fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
ret=1 ret=1
@ -278,11 +272,7 @@ run() {
if [ -d zeek-testing ]; then if [ -d zeek-testing ]; then
cd zeek-testing cd zeek-testing
if [ "${BUILD_DISTRO}" != "${LEAK_TEST_DISTRO}" ]; then
make make
else
make leaks
fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
showdiag showdiag
@ -294,11 +284,7 @@ run() {
if [ -d zeek-testing-private ]; then if [ -d zeek-testing-private ]; then
cd zeek-testing-private cd zeek-testing-private
if [ "${BUILD_DISTRO}" != "${LEAK_TEST_DISTRO}" ]; then
make make
else
make leaks
fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
showdiag showdiag

View file

@ -20,9 +20,6 @@ RUN apt-get update && apt-get -y install \
sqlite3 \ sqlite3 \
curl \ curl \
wget \ wget \
google-perftools \
libgoogle-perftools4 \
libgoogle-perftools-dev \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Many distros adhere to PEP 394's recommendation for `python` = `python2` so # Many distros adhere to PEP 394's recommendation for `python` = `python2` so

6
configure vendored
View file

@ -27,6 +27,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
ccache installation and CMake 3.10+) ccache installation and CMake 3.10+)
--toolchain=PATH path to a CMAKE_TOOLCHAIN_FILE --toolchain=PATH path to a CMAKE_TOOLCHAIN_FILE
(useful for cross-compiling) (useful for cross-compiling)
--sanitizers=LIST comma-separated list of sanitizer names to enable
Installation Directories: Installation Directories:
--prefix=PREFIX installation directory [/usr/local/zeek] --prefix=PREFIX installation directory [/usr/local/zeek]
@ -57,7 +58,6 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--disable-auxtools don't build or install auxiliary tools --disable-auxtools don't build or install auxiliary tools
--disable-python don't try to build python bindings for Broker --disable-python don't try to build python bindings for Broker
--disable-broker-tests don't try to build Broker unit tests --disable-broker-tests don't try to build Broker unit tests
--sanitizers=SANITIZERS comma-separated list of Clang sanitizers to enable
Required Packages in Non-Standard Locations: Required Packages in Non-Standard Locations:
--with-openssl=PATH path to OpenSSL install root --with-openssl=PATH path to OpenSSL install root
@ -154,7 +154,7 @@ append_cache_entry INSTALL_AUX_TOOLS BOOL true
append_cache_entry INSTALL_ZEEKCTL BOOL true append_cache_entry INSTALL_ZEEKCTL BOOL true
append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING append_cache_entry CPACK_SOURCE_IGNORE_FILES STRING
append_cache_entry ENABLE_MOBILE_IPV6 BOOL false append_cache_entry ENABLE_MOBILE_IPV6 BOOL false
append_cache_entry SANITIZERS STRING "" append_cache_entry ZEEK_SANITIZERS STRING ""
# parse arguments # parse arguments
while [ $# -ne 0 ]; do while [ $# -ne 0 ]; do
@ -240,7 +240,7 @@ while [ $# -ne 0 ]; do
append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL true append_cache_entry ENABLE_PERFTOOLS_DEBUG BOOL true
;; ;;
--sanitizers=*) --sanitizers=*)
append_cache_entry SANITIZERS STRING $optarg append_cache_entry ZEEK_SANITIZERS STRING $optarg
;; ;;
--enable-jemalloc) --enable-jemalloc)
append_cache_entry ENABLE_JEMALLOC BOOL true append_cache_entry ENABLE_JEMALLOC BOOL true

View file

@ -15,6 +15,17 @@ Brofiler::Brofiler()
Brofiler::~Brofiler() Brofiler::~Brofiler()
{ {
for ( auto& s : stmts )
Unref(s);
}
void Brofiler::AddStmt(Stmt* s)
{
if ( ignoring != 0 )
return;
::Ref(s);
stmts.push_back(s);
} }
bool Brofiler::ReadStats() bool Brofiler::ReadStats()
@ -109,7 +120,7 @@ bool Brofiler::WriteStats()
return false; return false;
} }
for ( list<const Stmt*>::const_iterator it = stmts.begin(); for ( list<Stmt*>::const_iterator it = stmts.begin();
it != stmts.end(); ++it ) it != stmts.end(); ++it )
{ {
ODesc location_info; ODesc location_info;

View file

@ -38,13 +38,13 @@ public:
void IncIgnoreDepth() { ignoring++; } void IncIgnoreDepth() { ignoring++; }
void DecIgnoreDepth() { ignoring--; } void DecIgnoreDepth() { ignoring--; }
void AddStmt(const Stmt* s) { if ( ignoring == 0 ) stmts.push_back(s); } void AddStmt(Stmt* s);
private: private:
/** /**
* The current, global Brofiler instance creates this list at parse-time. * The current, global Brofiler instance creates this list at parse-time.
*/ */
list<const Stmt*> stmts; list<Stmt*> stmts;
/** /**
* Indicates whether new statments will not be considered as part of * Indicates whether new statments will not be considered as part of

View file

@ -1404,7 +1404,7 @@ void DNS_Mgr::DoProcess()
{ {
AsyncRequest* req = asyncs_timeouts.top(); AsyncRequest* req = asyncs_timeouts.top();
if ( req->time + DNS_TIMEOUT > current_time() ) if ( req->time + DNS_TIMEOUT > current_time() && ! terminating )
break; break;
if ( ! req->processed ) if ( ! req->processed )

View file

@ -4339,6 +4339,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing,
// Install a dummy version of the function globally for use only // Install a dummy version of the function globally for use only
// when broker provides a closure. // when broker provides a closure.
::Ref(ingredients->body);
BroFunc* dummy_func = new BroFunc( BroFunc* dummy_func = new BroFunc(
ingredients->id, ingredients->id,
ingredients->body, ingredients->body,
@ -4378,6 +4379,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing,
dummy_func->SetName(my_name.c_str()); dummy_func->SetName(my_name.c_str());
Val* v = new Val(dummy_func); Val* v = new Val(dummy_func);
Unref(dummy_func);
id->SetVal(v); // id will unref v when its done. id->SetVal(v); // id will unref v when its done.
id->SetType(ingredients->id->Type()->Ref()); id->SetType(ingredients->id->Type()->Ref());
id->SetConst(); id->SetConst();
@ -4385,6 +4387,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr<function_ingredients> arg_ing,
Val* LambdaExpr::Eval(Frame* f) const Val* LambdaExpr::Eval(Frame* f) const
{ {
::Ref(ingredients->body);
BroFunc* lamb = new BroFunc( BroFunc* lamb = new BroFunc(
ingredients->id, ingredients->id,
ingredients->body, ingredients->body,
@ -4398,7 +4401,9 @@ Val* LambdaExpr::Eval(Frame* f) const
// Allows for lookups by the receiver. // Allows for lookups by the receiver.
lamb->SetName(my_name.c_str()); lamb->SetName(my_name.c_str());
return new Val(lamb); auto rval = new Val(lamb);
Unref(lamb);
return rval;
} }
void LambdaExpr::ExprDescribe(ODesc* d) const void LambdaExpr::ExprDescribe(ODesc* d) const

View file

@ -31,20 +31,54 @@ Frame::Frame(int arg_size, const BroFunc* func, const val_list* fn_args)
Frame::~Frame() Frame::~Frame()
{ {
for ( auto& func : functions_with_closure_frame_reference )
{
func->StrengthenClosureReference(this);
Unref(func);
}
// Deleting a Frame that is a view is a no-op. // Deleting a Frame that is a view is a no-op.
Unref(trigger); Unref(trigger);
if ( ! weak_closure_ref )
Unref(closure); Unref(closure);
for ( auto& i : outer_ids ) for ( auto& i : outer_ids )
Unref(i); Unref(i);
Release(); Release();
delete [] weak_refs;
} }
void Frame::SetElement(int n, Val* v) void Frame::AddFunctionWithClosureRef(BroFunc* func)
{ {
Unref(frame[n]); ::Ref(func);
functions_with_closure_frame_reference.emplace_back(func);
}
void Frame::SetElement(int n, Val* v, bool weak_ref)
{
UnrefElement(n);
frame[n] = v; frame[n] = v;
if ( weak_ref )
{
if ( ! weak_refs )
{
weak_refs = new bool[size];
for ( auto i = 0; i < size; ++i )
weak_refs[i] = false;
}
weak_refs[n] = true;
}
else
{
if ( weak_refs )
weak_refs[n] = false;
}
} }
void Frame::SetElement(const ID* id, Val* v) void Frame::SetElement(const ID* id, Val* v)
@ -62,8 +96,15 @@ void Frame::SetElement(const ID* id, Val* v)
if ( offset_map.size() ) if ( offset_map.size() )
{ {
auto where = offset_map.find(std::string(id->Name())); auto where = offset_map.find(std::string(id->Name()));
if ( where != offset_map.end() ) if ( where != offset_map.end() )
SetElement(where->second, v); {
// Need to add a Ref to 'v' since the SetElement() for
// id->Offset() below is otherwise responsible for keeping track
// of the implied reference count of the passed-in 'v' argument.
// i.e. if we end up storing it twice, we need an addition Ref.
SetElement(where->second, v->Ref());
}
} }
SetElement(id->Offset(), v); SetElement(id->Offset(), v);
@ -92,7 +133,7 @@ void Frame::Reset(int startIdx)
{ {
for ( int i = startIdx; i < size; ++i ) for ( int i = startIdx; i < size; ++i )
{ {
Unref(frame[i]); UnrefElement(i);
frame[i] = 0; frame[i] = 0;
} }
} }
@ -100,7 +141,7 @@ void Frame::Reset(int startIdx)
void Frame::Release() void Frame::Release()
{ {
for ( int i = 0; i < size; ++i ) for ( int i = 0; i < size; ++i )
Unref(frame[i]); UnrefElement(i);
delete [] frame; delete [] frame;
} }
@ -145,7 +186,34 @@ Frame* Frame::Clone() const
return other; return other;
} }
Frame* Frame::SelectiveClone(const id_list& selection) const static bool val_is_func(Val* v, BroFunc* func)
{
if ( v->Type()->Tag() != TYPE_FUNC )
return false;
return v->AsFunc() == func;
}
static Val* clone_if_not_func(Val** frame, int offset, BroFunc* func,
Frame* other)
{
auto v = frame[offset];
if ( ! v )
return nullptr;
if ( val_is_func(v, func) )
{
other->SetElement(offset, v, true);
return v;
}
auto rval = v->Clone();
other->SetElement(offset, rval);
return rval;
}
Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
{ {
if ( selection.length() == 0 ) if ( selection.length() == 0 )
return nullptr; return nullptr;
@ -171,7 +239,7 @@ Frame* Frame::SelectiveClone(const id_list& selection) const
auto where = offset_map.find(std::string(id->Name())); auto where = offset_map.find(std::string(id->Name()));
if ( where != offset_map.end() ) if ( where != offset_map.end() )
{ {
other->frame[where->second] = frame[where->second]->Clone(); clone_if_not_func(frame, where->second, func, other);
continue; continue;
} }
} }
@ -179,7 +247,7 @@ Frame* Frame::SelectiveClone(const id_list& selection) const
if ( ! frame[id->Offset()] ) if ( ! frame[id->Offset()] )
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name()); reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
other->frame[id->Offset()] = frame[id->Offset()]->Clone(); clone_if_not_func(frame, id->Offset(), func, other);
} }
/** /**
@ -379,6 +447,7 @@ std::pair<bool, Frame*> Frame::Unserialize(const broker::vector& data)
// Frame takes ownership of unref'ing elements in outer_ids // Frame takes ownership of unref'ing elements in outer_ids
rf->outer_ids = std::move(outer_ids); rf->outer_ids = std::move(outer_ids);
rf->closure = closure; rf->closure = closure;
rf->weak_closure_ref = false;
for ( int i = 0; i < frame_size; ++i ) for ( int i = 0; i < frame_size; ++i )
{ {
@ -437,7 +506,7 @@ void Frame::CaptureClosure(Frame* c, id_list arg_outer_ids)
closure = c; closure = c;
if ( closure ) if ( closure )
Ref(closure); weak_closure_ref = true;
/** /**
* Want to capture closures by copy? * Want to capture closures by copy?

View file

@ -44,8 +44,11 @@ public:
* *
* @param n the index to set * @param n the index to set
* @param v the value to set it to * @param v the value to set it to
* @param weak_ref whether the frame owns the value and should unref
* it upon destruction. Used to break circular references between
* lambda functions and closure frames.
*/ */
void SetElement(int n, Val* v); void SetElement(int n, Val* v, bool weak_ref = false);
/** /**
* Associates *id* and *v* in the frame. Future lookups of * Associates *id* and *v* in the frame. Future lookups of
@ -149,7 +152,7 @@ public:
* *selection* have been cloned. All other values are made to be * *selection* have been cloned. All other values are made to be
* null. * null.
*/ */
Frame* SelectiveClone(const id_list& selection) const; Frame* SelectiveClone(const id_list& selection, BroFunc* func) const;
/** /**
* Serializes the Frame into a Broker representation. * Serializes the Frame into a Broker representation.
@ -215,8 +218,28 @@ public:
void SetDelayed() { delayed = true; } void SetDelayed() { delayed = true; }
bool HasDelayed() const { return delayed; } bool HasDelayed() const { return delayed; }
/**
* Track a new function that refers to this frame for use as a closure.
* This frame's destructor will then upgrade that functions reference
* from weak to strong (by making a copy). The initial use of
* weak references prevents unbreakable circular references that
* otherwise cause memory leaks.
*/
void AddFunctionWithClosureRef(BroFunc* func);
private: private:
/**
* Unrefs the value at offset 'n' frame unless it's a weak reference.
*/
void UnrefElement(int n)
{
if ( weak_refs && weak_refs[n] )
return;
Unref(frame[n]);
}
/** Have we captured this id? */ /** Have we captured this id? */
bool IsOuterID(const ID* in) const; bool IsOuterID(const ID* in) const;
@ -242,8 +265,13 @@ private:
/** Associates ID's offsets with values. */ /** Associates ID's offsets with values. */
Val** frame; Val** frame;
/** Values that are weakly referenced by the frame. Used to
* prevent circular reference memory leaks in lambda/closures */
bool* weak_refs = nullptr;
/** The enclosing frame of this frame. */ /** The enclosing frame of this frame. */
Frame* closure; Frame* closure;
bool weak_closure_ref = false;
/** ID's used in this frame from the enclosing frame. */ /** ID's used in this frame from the enclosing frame. */
id_list outer_ids; id_list outer_ids;
@ -268,6 +296,8 @@ private:
Trigger* trigger; Trigger* trigger;
const CallExpr* call; const CallExpr* call;
bool delayed; bool delayed;
std::vector<BroFunc*> functions_with_closure_frame_reference;
}; };
/** /**

View file

@ -132,6 +132,7 @@ Func* Func::DoClone()
{ {
// By default, ok just to return a reference. Func does not have any state // By default, ok just to return a reference. Func does not have any state
// that is different across instances. // that is different across instances.
::Ref(this);
return this; return this;
} }
@ -286,6 +287,8 @@ BroFunc::~BroFunc()
{ {
std::for_each(bodies.begin(), bodies.end(), std::for_each(bodies.begin(), bodies.end(),
[](Body& b) { Unref(b.stmts); }); [](Body& b) { Unref(b.stmts); });
if ( ! weak_closure_ref )
Unref(closure); Unref(closure);
} }
@ -490,14 +493,35 @@ void BroFunc::AddClosure(id_list ids, Frame* f)
SetClosureFrame(f); SetClosureFrame(f);
} }
bool BroFunc::StrengthenClosureReference(Frame* f)
{
if ( closure != f )
return false;
if ( ! weak_closure_ref )
return false;
closure = closure->SelectiveClone(outer_ids, this);
weak_closure_ref = false;
return true;
}
void BroFunc::SetClosureFrame(Frame* f) void BroFunc::SetClosureFrame(Frame* f)
{ {
if ( closure ) if ( closure )
reporter->InternalError("Tried to override closure for BroFunc %s.", reporter->InternalError("Tried to override closure for BroFunc %s.",
Name()); Name());
// Have to use weak references initially because otherwise Ref'ing the
// original frame creates a circular reference: the function holds a
// reference to the frame and the frame contains a reference to this
// function value. And we can't just do a shallow clone of the frame
// up front because the closure semantics in Zeek allow mutating
// the outer frame.
closure = f; closure = f;
Ref(closure); weak_closure_ref = true;
f->AddFunctionWithClosureRef(this);
} }
bool BroFunc::UpdateClosure(const broker::vector& data) bool BroFunc::UpdateClosure(const broker::vector& data)
@ -510,9 +534,10 @@ bool BroFunc::UpdateClosure(const broker::vector& data)
if ( new_closure ) if ( new_closure )
new_closure->SetFunction(this); new_closure->SetFunction(this);
if ( closure ) if ( ! weak_closure_ref )
Unref(closure); Unref(closure);
weak_closure_ref = false;
closure = new_closure; closure = new_closure;
return true; return true;
@ -528,7 +553,8 @@ Func* BroFunc::DoClone()
CopyStateInto(other); CopyStateInto(other);
other->frame_size = frame_size; other->frame_size = frame_size;
other->closure = closure ? closure->SelectiveClone(outer_ids) : nullptr; other->closure = closure ? closure->SelectiveClone(outer_ids, this) : nullptr;
other->weak_closure_ref = false;
other->outer_ids = outer_ids; other->outer_ids = outer_ids;
return other; return other;
@ -811,3 +837,68 @@ bool check_built_in_call(BuiltinFunc* f, CallExpr* call)
return true; return true;
} }
// Gets a function's priority from its Scope's attributes. Errors if it sees any
// problems.
static int get_func_priority(const attr_list& attrs)
{
int priority = 0;
for ( const auto& a : attrs )
{
if ( a->Tag() == ATTR_DEPRECATED )
continue;
if ( a->Tag() != ATTR_PRIORITY )
{
a->Error("illegal attribute for function body");
continue;
}
Val* v = a->AttrExpr()->Eval(0);
if ( ! v )
{
a->Error("cannot evaluate attribute expression");
continue;
}
if ( ! IsIntegral(v->Type()->Tag()) )
{
a->Error("expression is not of integral type");
continue;
}
priority = v->InternalInt();
}
return priority;
}
function_ingredients::function_ingredients(Scope* scope, Stmt* body)
{
frame_size = scope->Length();
inits = scope->GetInits();
this->scope = scope;
::Ref(this->scope);
id = scope->ScopeID();
::Ref(id);
auto attrs = scope->Attrs();
priority = (attrs ? get_func_priority(*attrs) : 0);
this->body = body;
::Ref(this->body);
}
function_ingredients::~function_ingredients()
{
Unref(id);
Unref(body);
Unref(scope);
for ( const auto& i : *inits )
Unref(i);
delete inits;
}

View file

@ -114,6 +114,12 @@ public:
*/ */
bool UpdateClosure(const broker::vector& data); bool UpdateClosure(const broker::vector& data);
/**
* If the function's closure is a weak reference to the given frame,
* upgrade to a strong reference of a shallow clone of that frame.
*/
bool StrengthenClosureReference(Frame* f);
/** /**
* Serializes this function's closure. * Serializes this function's closure.
* *
@ -154,6 +160,7 @@ private:
id_list outer_ids; id_list outer_ids;
// The frame the BroFunc was initialized in. // The frame the BroFunc was initialized in.
Frame* closure = nullptr; Frame* closure = nullptr;
bool weak_closure_ref = false;
}; };
typedef Val* (*built_in_func)(Frame* frame, val_list* args); typedef Val* (*built_in_func)(Frame* frame, val_list* args);
@ -192,13 +199,20 @@ struct CallInfo {
// Struct that collects all the specifics defining a Func. Used for BroFuncs // Struct that collects all the specifics defining a Func. Used for BroFuncs
// with closures. // with closures.
struct function_ingredients { struct function_ingredients {
// Gathers all of the information from a scope and a function body needed
// to build a function.
function_ingredients(Scope* scope, Stmt* body);
~function_ingredients();
ID* id; ID* id;
Stmt* body; Stmt* body;
id_list* inits; id_list* inits;
int frame_size; int frame_size;
int priority; int priority;
Scope* scope; Scope* scope;
}; };
extern vector<CallInfo> call_stack; extern vector<CallInfo> call_stack;

View file

@ -65,6 +65,17 @@ void notifier::Registry::Modified(Modifiable* m)
i->second->Modified(m); i->second->Modified(m);
} }
void notifier::Registry::Terminate()
{
std::set<Receiver*> receivers;
for ( auto& r : registrations )
receivers.emplace(r.second);
for ( auto& r : receivers )
r->Terminate();
}
notifier::Modifiable::~Modifiable() notifier::Modifiable::~Modifiable()
{ {
if ( num_receivers ) if ( num_receivers )

View file

@ -30,6 +30,12 @@ public:
* @param m object that was modified * @param m object that was modified
*/ */
virtual void Modified(Modifiable* m) = 0; virtual void Modified(Modifiable* m) = 0;
/**
* Callback executed when notification registry is terminating and
* no further modifications can possibly occur.
*/
virtual void Terminate() { }
}; };
/** Singleton class tracking all notification requests globally. */ /** Singleton class tracking all notification requests globally. */
@ -69,6 +75,12 @@ public:
*/ */
void Unregister(Modifiable* m); void Unregister(Modifiable* m);
/**
* Notifies all receivers that no further modifications will occur
* as the registry is shutting down.
*/
void Terminate();
private: private:
friend class Modifiable; friend class Modifiable;

View file

@ -1,11 +1,25 @@
#include "PacketFilter.h" #include "PacketFilter.h"
void PacketFilter::DeleteFilter(void* data)
{
auto f = static_cast<Filter*>(data);
delete f;
}
PacketFilter::PacketFilter(bool arg_default)
{
default_match = arg_default;
src_filter.SetDeleteFunction(PacketFilter::DeleteFilter);
dst_filter.SetDeleteFunction(PacketFilter::DeleteFilter);
}
void PacketFilter::AddSrc(const IPAddr& src, uint32_t tcp_flags, double probability) void PacketFilter::AddSrc(const IPAddr& src, uint32_t tcp_flags, double probability)
{ {
Filter* f = new Filter; Filter* f = new Filter;
f->tcp_flags = tcp_flags; f->tcp_flags = tcp_flags;
f->probability = uint32_t(probability * RAND_MAX); f->probability = uint32_t(probability * RAND_MAX);
src_filter.Insert(src, 128, f); auto prev = static_cast<Filter*>(src_filter.Insert(src, 128, f));
delete prev;
} }
void PacketFilter::AddSrc(Val* src, uint32_t tcp_flags, double probability) void PacketFilter::AddSrc(Val* src, uint32_t tcp_flags, double probability)
@ -13,7 +27,8 @@ void PacketFilter::AddSrc(Val* src, uint32_t tcp_flags, double probability)
Filter* f = new Filter; Filter* f = new Filter;
f->tcp_flags = tcp_flags; f->tcp_flags = tcp_flags;
f->probability = uint32_t(probability * RAND_MAX); f->probability = uint32_t(probability * RAND_MAX);
src_filter.Insert(src, f); auto prev = static_cast<Filter*>(src_filter.Insert(src, f));
delete prev;
} }
void PacketFilter::AddDst(const IPAddr& dst, uint32_t tcp_flags, double probability) void PacketFilter::AddDst(const IPAddr& dst, uint32_t tcp_flags, double probability)
@ -21,7 +36,8 @@ void PacketFilter::AddDst(const IPAddr& dst, uint32_t tcp_flags, double probabil
Filter* f = new Filter; Filter* f = new Filter;
f->tcp_flags = tcp_flags; f->tcp_flags = tcp_flags;
f->probability = uint32_t(probability * RAND_MAX); f->probability = uint32_t(probability * RAND_MAX);
dst_filter.Insert(dst, 128, f); auto prev = static_cast<Filter*>(dst_filter.Insert(dst, 128, f));
delete prev;
} }
void PacketFilter::AddDst(Val* dst, uint32_t tcp_flags, double probability) void PacketFilter::AddDst(Val* dst, uint32_t tcp_flags, double probability)
@ -29,27 +45,36 @@ void PacketFilter::AddDst(Val* dst, uint32_t tcp_flags, double probability)
Filter* f = new Filter; Filter* f = new Filter;
f->tcp_flags = tcp_flags; f->tcp_flags = tcp_flags;
f->probability = uint32_t(probability * RAND_MAX); f->probability = uint32_t(probability * RAND_MAX);
dst_filter.Insert(dst, f); auto prev = static_cast<Filter*>(dst_filter.Insert(dst, f));
delete prev;
} }
bool PacketFilter::RemoveSrc(const IPAddr& src) bool PacketFilter::RemoveSrc(const IPAddr& src)
{ {
return src_filter.Remove(src, 128) != 0; auto f = static_cast<Filter*>(src_filter.Remove(src, 128));
delete f;
return f != nullptr;
} }
bool PacketFilter::RemoveSrc(Val* src) bool PacketFilter::RemoveSrc(Val* src)
{ {
return src_filter.Remove(src) != NULL; auto f = static_cast<Filter*>(src_filter.Remove(src));
delete f;
return f != nullptr;
} }
bool PacketFilter::RemoveDst(const IPAddr& dst) bool PacketFilter::RemoveDst(const IPAddr& dst)
{ {
return dst_filter.Remove(dst, 128) != NULL; auto f = static_cast<Filter*>(dst_filter.Remove(dst, 128));
delete f;
return f != nullptr;
} }
bool PacketFilter::RemoveDst(Val* dst) bool PacketFilter::RemoveDst(Val* dst)
{ {
return dst_filter.Remove(dst) != NULL; auto f = static_cast<Filter*>(dst_filter.Remove(dst));
delete f;
return f != nullptr;
} }
bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen) bool PacketFilter::Match(const IP_Hdr* ip, int len, int caplen)

View file

@ -7,7 +7,7 @@
class PacketFilter { class PacketFilter {
public: public:
explicit PacketFilter(bool arg_default) { default_match = arg_default; } explicit PacketFilter(bool arg_default);
~PacketFilter() {} ~PacketFilter() {}
// Drops all packets from a particular source (which may be given // Drops all packets from a particular source (which may be given
@ -34,6 +34,8 @@ private:
uint32_t probability; uint32_t probability;
}; };
static void DeleteFilter(void* data);
bool MatchFilter(const Filter& f, const IP_Hdr& ip, int len, int caplen); bool MatchFilter(const Filter& f, const IP_Hdr& ip, int len, int caplen);
bool default_match; bool default_match;

View file

@ -18,8 +18,8 @@ private:
}; };
public: public:
PrefixTable() { tree = New_Patricia(128); } PrefixTable() { tree = New_Patricia(128); delete_function = nullptr; }
~PrefixTable() { Destroy_Patricia(tree, 0); } ~PrefixTable() { Destroy_Patricia(tree, delete_function); }
// Addr in network byte order. If data is zero, acts like a set. // Addr in network byte order. If data is zero, acts like a set.
// Returns ptr to old data if already existing. // Returns ptr to old data if already existing.
@ -43,7 +43,10 @@ public:
void* Remove(const IPAddr& addr, int width); void* Remove(const IPAddr& addr, int width);
void* Remove(const Val* value); void* Remove(const Val* value);
void Clear() { Clear_Patricia(tree, 0); } void Clear() { Clear_Patricia(tree, delete_function); }
// Sets a function to call for each node when table is cleared/destroyed.
void SetDeleteFunction(data_fn_t del_fn) { delete_function = del_fn; }
iterator InitIterator(); iterator InitIterator();
void* GetNext(iterator* i); void* GetNext(iterator* i);
@ -53,4 +56,5 @@ private:
static IPPrefix PrefixToIPPrefix(prefix_t* p); static IPPrefix PrefixToIPPrefix(prefix_t* p);
patricia_tree_t* tree; patricia_tree_t* tree;
data_fn_t delete_function;
}; };

View file

@ -171,6 +171,27 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
Unref(this); Unref(this);
} }
void Trigger::Terminate()
{
if ( is_return )
{
auto parent = frame->GetTrigger();
if ( ! parent->Disabled() )
{
// If the trigger was already disabled due to interpreter
// exception, an Unref already happened at that point.
parent->Disable();
Unref(parent);
}
frame->ClearTrigger();
}
Disable();
Unref(this);
}
Trigger::~Trigger() Trigger::~Trigger()
{ {
DBG_LOG(DBG_NOTIFIERS, "%s: deleting", Name()); DBG_LOG(DBG_NOTIFIERS, "%s: deleting", Name());

View file

@ -62,6 +62,10 @@ public:
// later to avoid race conditions. // later to avoid race conditions.
void Modified(notifier::Modifiable* m) override void Modified(notifier::Modifiable* m) override
{ QueueTrigger(this); } { QueueTrigger(this); }
// Overridden from notifer::Receiver. If we're still waiting
// on an ID/Val to be modified at termination time, we can't hope
// for any further progress to be made, so just Unref ourselves.
void Terminate() override;
const char* Name() const; const char* Name() const;

View file

@ -120,7 +120,12 @@ Val* Val::DoClone(CloneState* state)
// Derived classes are responsible for this. Exception: // Derived classes are responsible for this. Exception:
// Functions and files. There aren't any derived classes. // Functions and files. There aren't any derived classes.
if ( type->Tag() == TYPE_FUNC ) if ( type->Tag() == TYPE_FUNC )
return new Val(AsFunc()->DoClone()); {
auto c = AsFunc()->DoClone();
auto rval = new Val(c);
Unref(c);
return rval;
}
if ( type->Tag() == TYPE_FILE ) if ( type->Tag() == TYPE_FILE )
{ {
@ -479,11 +484,7 @@ static ZeekJson BuildJSON(Val* val, bool only_loggable=false, RE_Matcher* re=nul
ODesc d; ODesc d;
d.SetStyle(RAW_STYLE); d.SetStyle(RAW_STYLE);
val->Describe(&d); val->Describe(&d);
j = string(reinterpret_cast<const char*>(d.Bytes()), d.Len());
auto* bs = new BroString(1, d.TakeBytes(), d.Len());
j = string((char*)bs->Bytes(), bs->Len());
delete bs;
break; break;
} }
@ -495,11 +496,7 @@ static ZeekJson BuildJSON(Val* val, bool only_loggable=false, RE_Matcher* re=nul
ODesc d; ODesc d;
d.SetStyle(RAW_STYLE); d.SetStyle(RAW_STYLE);
val->Describe(&d); val->Describe(&d);
j = json_escape_utf8(string(reinterpret_cast<const char*>(d.Bytes()), d.Len()));
auto* bs = new BroString(1, d.TakeBytes(), d.Len());
j = json_escape_utf8(string((char*)bs->Bytes(), bs->Len()));
delete bs;
break; break;
} }

View file

@ -416,13 +416,30 @@ public:
: scope(s) { } : scope(s) { }
virtual TraversalCode PreExpr(const Expr*); virtual TraversalCode PreExpr(const Expr*);
virtual TraversalCode PostExpr(const Expr*);
Scope* scope; Scope* scope;
vector<const NameExpr*> outer_id_references; vector<const NameExpr*> outer_id_references;
int lambda_depth = 0;
// Note: think we really ought to toggle this to false to prevent
// considering locals within inner-lambdas as "outer", but other logic
// for "selective cloning" and locating IDs in the closure chain may
// depend on current behavior and also needs to be changed.
bool search_inner_lambdas = true;
}; };
TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr) TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr)
{ {
if ( expr->Tag() == EXPR_LAMBDA )
++lambda_depth;
if ( lambda_depth > 0 && ! search_inner_lambdas )
// Don't inspect the bodies of inner lambdas as they will have their
// own traversal to find outer IDs and we don't want to detect
// references to local IDs inside and accidentally treat them as
// "outer" since they can't be found in current scope.
return TC_CONTINUE;
if ( expr->Tag() != EXPR_NAME ) if ( expr->Tag() != EXPR_NAME )
return TC_CONTINUE; return TC_CONTINUE;
@ -438,45 +455,20 @@ TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr)
return TC_CONTINUE; return TC_CONTINUE;
} }
// Gets a function's priority from its Scope's attributes. Errors if it sees any TraversalCode OuterIDBindingFinder::PostExpr(const Expr* expr)
// problems.
static int get_func_priotity(const attr_list& attrs)
{ {
int priority = 0; if ( expr->Tag() == EXPR_LAMBDA )
for ( const auto& a : attrs )
{ {
if ( a->Tag() == ATTR_DEPRECATED ) --lambda_depth;
continue; assert(lambda_depth >= 0);
if ( a->Tag() != ATTR_PRIORITY )
{
a->Error("illegal attribute for function body");
continue;
} }
Val* v = a->AttrExpr()->Eval(0); return TC_CONTINUE;
if ( ! v )
{
a->Error("cannot evaluate attribute expression");
continue;
}
if ( ! IsIntegral(v->Type()->Tag()) )
{
a->Error("expression is not of integral type");
continue;
}
priority = v->InternalInt();
}
return priority;
} }
void end_func(Stmt* body) void end_func(Stmt* body)
{ {
std::unique_ptr<function_ingredients> ingredients = gather_function_ingredients(pop_scope(), body); auto ingredients = std::make_unique<function_ingredients>(pop_scope(), body);
if ( streq(ingredients->id->Name(), "anonymous-function") ) if ( streq(ingredients->id->Name(), "anonymous-function") )
{ {
@ -508,24 +500,10 @@ void end_func(Stmt* body)
} }
ingredients->id->ID_Val()->AsFunc()->SetScope(ingredients->scope); ingredients->id->ID_Val()->AsFunc()->SetScope(ingredients->scope);
} // Note: ideally, something would take ownership of this memory until the
// end of script execution, but that's essentially the same as the
std::unique_ptr<function_ingredients> gather_function_ingredients(Scope* scope, Stmt* body) // lifetime of the process at the moment, so ok to "leak" it.
{ ingredients.release();
auto ingredients = std::make_unique<function_ingredients>();
ingredients->frame_size = scope->Length();
ingredients->inits = scope->GetInits();
ingredients->scope = scope;
ingredients->id = scope->ScopeID();
auto attrs = scope->Attrs();
ingredients->priority = (attrs ? get_func_priotity(*attrs) : 0);
ingredients->body = body;
return ingredients;
} }
Val* internal_val(const char* name) Val* internal_val(const char* name)
@ -548,7 +526,14 @@ id_list gather_outer_ids(Scope* scope, Stmt* body)
id_list idl ( cb.outer_id_references.size() ); id_list idl ( cb.outer_id_references.size() );
for ( size_t i = 0; i < cb.outer_id_references.size(); ++i ) for ( size_t i = 0; i < cb.outer_id_references.size(); ++i )
idl.append(cb.outer_id_references[i]->Id()); {
auto id = cb.outer_id_references[i]->Id();
if ( idl.is_member(id) )
continue;
idl.append(id);
}
return idl; return idl;
} }

View file

@ -26,11 +26,6 @@ extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
int is_redef, FuncType* t, attr_list* attrs = nullptr); int is_redef, FuncType* t, attr_list* attrs = nullptr);
extern void end_func(Stmt* body); extern void end_func(Stmt* body);
// Gathers all of the information from a scope and a function body needed to
// build a function and collects it into a function_ingredients struct.
// Gathered elements are not refeed.
extern std::unique_ptr<function_ingredients> gather_function_ingredients(Scope* scope, Stmt* body);
// Gather all IDs referenced inside a body that aren't part of a given scope. // Gather all IDs referenced inside a body that aren't part of a given scope.
extern id_list gather_outer_ids(Scope* scope, Stmt* body); extern id_list gather_outer_ids(Scope* scope, Stmt* body);

View file

@ -25,6 +25,13 @@ KRB_Analyzer::KRB_Analyzer(Connection* conn)
} }
#ifdef USE_KRB5 #ifdef USE_KRB5
static void warn_krb(const char* msg, krb5_context ctx, krb5_error_code code)
{
auto err = krb5_get_error_message(ctx, code);
reporter->Warning("%s (%s)", msg, err);
krb5_free_error_message(ctx, err);
}
void KRB_Analyzer::Initialize_Krb() void KRB_Analyzer::Initialize_Krb()
{ {
if ( BifConst::KRB::keytab->Len() == 0 ) if ( BifConst::KRB::keytab->Len() == 0 )
@ -40,14 +47,14 @@ void KRB_Analyzer::Initialize_Krb()
krb5_error_code retval = krb5_init_context(&krb_context); krb5_error_code retval = krb5_init_context(&krb_context);
if ( retval ) if ( retval )
{ {
reporter->Warning("KRB: Couldn't initialize the context (%s)", krb5_get_error_message(krb_context, retval)); warn_krb("KRB: Couldn't initialize the context", krb_context, retval);
return; return;
} }
retval = krb5_kt_resolve(krb_context, keytab_filename, &krb_keytab); retval = krb5_kt_resolve(krb_context, keytab_filename, &krb_keytab);
if ( retval ) if ( retval )
{ {
reporter->Warning("KRB: Couldn't resolve keytab (%s)", krb5_get_error_message(krb_context, retval)); warn_krb("KRB: Couldn't resolve keytab", krb_context, retval);
return; return;
} }
krb_available = true; krb_available = true;
@ -103,33 +110,44 @@ StringVal* KRB_Analyzer::GetAuthenticationInfo(const BroString* principal, const
krb5_error_code retval = krb5_sname_to_principal(krb_context, hostname->CheckString(), service->CheckString(), KRB5_NT_SRV_HST, &sprinc); krb5_error_code retval = krb5_sname_to_principal(krb_context, hostname->CheckString(), service->CheckString(), KRB5_NT_SRV_HST, &sprinc);
if ( retval ) if ( retval )
{ {
reporter->Warning("KRB: Couldn't generate principal name (%s)", krb5_get_error_message(krb_context, retval)); warn_krb("KRB: Couldn't generate principal name", krb_context, retval);
return nullptr; return nullptr;
} }
krb5_ticket tkt; auto tkt = static_cast<krb5_ticket*>(safe_malloc(sizeof(krb5_ticket)));
tkt.server = sprinc; memset(tkt, 0, sizeof(krb5_ticket));
tkt.enc_part.enctype = enctype;
tkt.enc_part.ciphertext.data = reinterpret_cast<char*>(ciphertext->Bytes()); tkt->server = sprinc;
tkt.enc_part.ciphertext.length = ciphertext->Len(); tkt->enc_part.enctype = enctype;
auto ctd = static_cast<char*>(safe_malloc(ciphertext->Len()));
memcpy(ctd, ciphertext->Bytes(), ciphertext->Len());
tkt->enc_part.ciphertext.data = ctd;
tkt->enc_part.ciphertext.length = ciphertext->Len();
retval = krb5_server_decrypt_ticket_keytab(krb_context, krb_keytab, tkt);
retval = krb5_server_decrypt_ticket_keytab(krb_context, krb_keytab, &tkt);
if ( retval ) if ( retval )
{ {
reporter->Warning("KRB: Couldn't decrypt ticket (%s)", krb5_get_error_message(krb_context, retval)); krb5_free_ticket(krb_context, tkt);
warn_krb("KRB: Couldn't decrypt ticket", krb_context, retval);
return nullptr; return nullptr;
} }
char* cp; char* cp;
retval = krb5_unparse_name(krb_context, tkt.enc_part2->client, &cp); retval = krb5_unparse_name(krb_context, tkt->enc_part2->client, &cp);
if ( retval ) if ( retval )
{ {
reporter->Warning("KRB: Couldn't unparse name (%s)", krb5_get_error_message(krb_context, retval)); krb5_free_ticket(krb_context, tkt);
warn_krb("KRB: Couldn't unparse name", krb_context, retval);
return nullptr; return nullptr;
} }
StringVal* ret = new StringVal(cp); StringVal* ret = new StringVal(cp);
krb5_free_unparsed_name(krb_context, cp); krb5_free_unparsed_name(krb_context, cp);
krb5_free_ticket(krb_context, tkt);
return ret; return ret;
#else #else

View file

@ -183,6 +183,23 @@ bool file_analysis::OCSP::EndOfFile()
} }
#if ( OPENSSL_VERSION_NUMBER >= 0x10100000L ) #if ( OPENSSL_VERSION_NUMBER >= 0x10100000L )
struct ASN1Seq {
ASN1Seq(const unsigned char** der_in, long length)
{ decoded = d2i_ASN1_SEQUENCE_ANY(nullptr, der_in, length); }
~ASN1Seq()
{ sk_ASN1_TYPE_pop_free(decoded, ASN1_TYPE_free); }
explicit operator bool() const
{ return decoded; }
operator ASN1_SEQUENCE_ANY*() const
{ return decoded; }
ASN1_SEQUENCE_ANY* decoded;
};
// Re-encode and then parse out ASN1 structures to get at what we need... // Re-encode and then parse out ASN1 structures to get at what we need...
/*- BasicOCSPResponse ::= SEQUENCE { /*- BasicOCSPResponse ::= SEQUENCE {
* tbsResponseData ResponseData, * tbsResponseData ResponseData,
@ -209,8 +226,7 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
const unsigned char* const_der_basic_resp_dat = der_basic_resp_dat; const unsigned char* const_der_basic_resp_dat = der_basic_resp_dat;
auto bseq = d2i_ASN1_SEQUENCE_ANY(nullptr, &const_der_basic_resp_dat, ASN1Seq bseq{&const_der_basic_resp_dat, der_basic_resp_len};
der_basic_resp_len);
if ( ! bseq ) if ( ! bseq )
{ {
@ -220,7 +236,6 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
if ( sk_ASN1_TYPE_num(bseq) < 3 ) if ( sk_ASN1_TYPE_num(bseq) < 3 )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
@ -230,7 +245,6 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
if ( ASN1_TYPE_get(aseq_type) != V_ASN1_SEQUENCE ) if ( ASN1_TYPE_get(aseq_type) != V_ASN1_SEQUENCE )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
@ -239,19 +253,16 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
auto aseq_len = ASN1_STRING_length(aseq_str); auto aseq_len = ASN1_STRING_length(aseq_str);
auto aseq_dat = ASN1_STRING_get0_data(aseq_str); auto aseq_dat = ASN1_STRING_get0_data(aseq_str);
auto aseq = d2i_ASN1_SEQUENCE_ANY(nullptr, &aseq_dat, aseq_len); ASN1Seq aseq{&aseq_dat, aseq_len};
if ( ! aseq ) if ( ! aseq )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
if ( sk_ASN1_TYPE_num(aseq) < 1 ) if ( sk_ASN1_TYPE_num(aseq) < 1 )
{ {
sk_ASN1_TYPE_free(aseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
@ -261,8 +272,6 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
if ( ASN1_TYPE_get(alg_obj_type) != V_ASN1_OBJECT ) if ( ASN1_TYPE_get(alg_obj_type) != V_ASN1_OBJECT )
{ {
sk_ASN1_TYPE_free(aseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
@ -273,8 +282,6 @@ static StringVal* parse_basic_resp_sig_alg(OCSP_BASICRESP* basic_resp,
auto rval = new StringVal(alg_len, buf); auto rval = new StringVal(alg_len, buf);
BIO_reset(bio); BIO_reset(bio);
sk_ASN1_TYPE_free(aseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return rval; return rval;
} }
@ -291,8 +298,7 @@ static Val* parse_basic_resp_data_version(OCSP_BASICRESP* basic_resp)
const unsigned char* const_der_basic_resp_dat = der_basic_resp_dat; const unsigned char* const_der_basic_resp_dat = der_basic_resp_dat;
auto bseq = d2i_ASN1_SEQUENCE_ANY(nullptr, &const_der_basic_resp_dat, ASN1Seq bseq{&const_der_basic_resp_dat, der_basic_resp_len};
der_basic_resp_len);
if ( ! bseq ) if ( ! bseq )
{ {
@ -302,7 +308,6 @@ static Val* parse_basic_resp_data_version(OCSP_BASICRESP* basic_resp)
if ( sk_ASN1_TYPE_num(bseq) < 3 ) if ( sk_ASN1_TYPE_num(bseq) < 3 )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetCount(-1); return val_mgr->GetCount(-1);
} }
@ -312,7 +317,6 @@ static Val* parse_basic_resp_data_version(OCSP_BASICRESP* basic_resp)
if ( ASN1_TYPE_get(dseq_type) != V_ASN1_SEQUENCE ) if ( ASN1_TYPE_get(dseq_type) != V_ASN1_SEQUENCE )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetCount(-1); return val_mgr->GetCount(-1);
} }
@ -321,19 +325,16 @@ static Val* parse_basic_resp_data_version(OCSP_BASICRESP* basic_resp)
auto dseq_len = ASN1_STRING_length(dseq_str); auto dseq_len = ASN1_STRING_length(dseq_str);
auto dseq_dat = ASN1_STRING_get0_data(dseq_str); auto dseq_dat = ASN1_STRING_get0_data(dseq_str);
auto dseq = d2i_ASN1_SEQUENCE_ANY(nullptr, &dseq_dat, dseq_len); ASN1Seq dseq{&dseq_dat, dseq_len};
if ( ! dseq ) if ( ! dseq )
{ {
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
if ( sk_ASN1_TYPE_num(dseq) < 1 ) if ( sk_ASN1_TYPE_num(dseq) < 1 )
{ {
sk_ASN1_TYPE_free(dseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetEmptyString(); return val_mgr->GetEmptyString();
} }
@ -351,16 +352,12 @@ static Val* parse_basic_resp_data_version(OCSP_BASICRESP* basic_resp)
if ( ASN1_TYPE_get(version_type) != V_ASN1_INTEGER ) if ( ASN1_TYPE_get(version_type) != V_ASN1_INTEGER )
{ {
sk_ASN1_TYPE_free(dseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
// Not present, use default value. // Not present, use default value.
return val_mgr->GetCount(0); return val_mgr->GetCount(0);
} }
uint64_t asn1_int = ASN1_INTEGER_get(version_type->value.integer); uint64_t asn1_int = ASN1_INTEGER_get(version_type->value.integer);
sk_ASN1_TYPE_free(dseq);
sk_ASN1_TYPE_free(bseq);
OPENSSL_free(der_basic_resp_dat); OPENSSL_free(der_basic_resp_dat);
return val_mgr->GetCount(asn1_int); return val_mgr->GetCount(asn1_int);
} }
@ -375,8 +372,7 @@ static uint64_t parse_request_version(OCSP_REQUEST* req)
if ( ! der_req_dat ) if ( ! der_req_dat )
return -1; return -1;
auto rseq = d2i_ASN1_SEQUENCE_ANY(nullptr, &const_der_req_dat, ASN1Seq rseq{&const_der_req_dat, der_req_len};
der_req_len);
if ( ! rseq ) if ( ! rseq )
{ {
@ -386,7 +382,6 @@ static uint64_t parse_request_version(OCSP_REQUEST* req)
if ( sk_ASN1_TYPE_num(rseq) < 1 ) if ( sk_ASN1_TYPE_num(rseq) < 1 )
{ {
sk_ASN1_TYPE_free(rseq);
OPENSSL_free(der_req_dat); OPENSSL_free(der_req_dat);
return -1; return -1;
} }
@ -396,14 +391,12 @@ static uint64_t parse_request_version(OCSP_REQUEST* req)
if ( ASN1_TYPE_get(version_type) != V_ASN1_INTEGER ) if ( ASN1_TYPE_get(version_type) != V_ASN1_INTEGER )
{ {
sk_ASN1_TYPE_free(rseq);
OPENSSL_free(der_req_dat); OPENSSL_free(der_req_dat);
// Not present, use default value. // Not present, use default value.
return 0; return 0;
} }
uint64_t asn1_int = ASN1_INTEGER_get(version_type->value.integer); uint64_t asn1_int = ASN1_INTEGER_get(version_type->value.integer);
sk_ASN1_TYPE_free(rseq);
OPENSSL_free(der_req_dat); OPENSSL_free(der_req_dat);
return asn1_int; return asn1_int;
} }

View file

@ -22,6 +22,12 @@ public:
config.description = "X509 and OCSP analyzer"; config.description = "X509 and OCSP analyzer";
return config; return config;
} }
void Done() override
{
plugin::Plugin::Done();
::file_analysis::X509::FreeRootStore();
}
} plugin; } plugin;
} }

View file

@ -18,6 +18,10 @@
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#include <openssl/err.h> #include <openssl/err.h>
namespace file_analysis {
std::map<Val*, X509_STORE*> X509::x509_stores;
}
using namespace file_analysis; using namespace file_analysis;
file_analysis::X509::X509(RecordVal* args, file_analysis::File* file) file_analysis::X509::X509(RecordVal* args, file_analysis::File* file)
@ -213,6 +217,47 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val, File* f)
return pX509Cert; return pX509Cert;
} }
X509_STORE* file_analysis::X509::GetRootStore(TableVal* root_certs)
{
// If this certificate store was built previously, just reuse the old one.
if ( x509_stores.count(root_certs) > 0 )
return x509_stores[root_certs];
X509_STORE* ctx = X509_STORE_new();
ListVal* idxs = root_certs->ConvertToPureList();
// Build the validation store
for ( int i = 0; i < idxs->Length(); ++i )
{
Val* key = idxs->Index(i);
StringVal *sv = root_certs->Lookup(key)->AsStringVal();
assert(sv);
const uint8_t* data = sv->Bytes();
::X509* x = d2i_X509(NULL, &data, sv->Len());
if ( ! x )
{
builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_get_error(),NULL)));
return 0;
}
X509_STORE_add_cert(ctx, x);
X509_free(x);
}
delete idxs;
// Save the newly constructed certificate store into the cacheing map.
x509_stores[root_certs] = ctx;
return ctx;
}
void file_analysis::X509::FreeRootStore()
{
for ( const auto& e : x509_stores )
X509_STORE_free(e.second);
}
void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex) void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex)
{ {
assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints); assert(OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == NID_basic_constraints);

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <map>
#include "OpaqueVal.h" #include "OpaqueVal.h"
#include "X509Common.h" #include "X509Common.h"
@ -89,6 +90,28 @@ public:
static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file) static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file)
{ return new X509(args, file); } { return new X509(args, file); }
/**
* Retrieves OpenSSL's representation of an X509 certificate store
* associated with a script-layer certificate root table variable/value.
* The underlying X509 store will be created if it has not been already,
* else the previously allocated one for the same table will be returned.
*
* @param root_certs The script-layer certificate root table value.
*
* @return OpenSSL's X509 store associated with the table value.
*/
static X509_STORE* GetRootStore(TableVal* root_certs);
/**
* Frees memory obtained from OpenSSL that is associated with the global
* X509 certificate store used by the Zeek scripting-layer. This primarily
* exists so leak checkers like LeakSanitizer don't count the
* globally-allocated mapping as a leak. Would be easy to suppress/ignore
* it, but that could accidentally silence cases where some new code
* mistakenly overwrites a table element without freeing it.
*/
static void FreeRootStore();
protected: protected:
X509(RecordVal* args, File* file); X509(RecordVal* args, File* file);
@ -102,6 +125,8 @@ private:
// Helpers for ParseCertificate. // Helpers for ParseCertificate.
static StringVal* KeyCurve(EVP_PKEY *key); static StringVal* KeyCurve(EVP_PKEY *key);
static unsigned int KeyLength(EVP_PKEY *key); static unsigned int KeyLength(EVP_PKEY *key);
/** X509 stores associated with global script-layer values */
static std::map<Val*, X509_STORE*> x509_stores;
}; };
/** /**

View file

@ -10,9 +10,6 @@
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/err.h> #include <openssl/err.h>
// This is the indexed map of X509 certificate stores.
static map<Val*, X509_STORE*> x509_stores;
// construct an error record // construct an error record
RecordVal* x509_result_record(uint64_t num, const char* reason, Val* chainVector = 0) RecordVal* x509_result_record(uint64_t num, const char* reason, Val* chainVector = 0)
{ {
@ -26,41 +23,6 @@ RecordVal* x509_result_record(uint64_t num, const char* reason, Val* chainVector
return rrecord; return rrecord;
} }
X509_STORE* x509_get_root_store(TableVal* root_certs)
{
// If this certificate store was built previously, just reuse the old one.
if ( x509_stores.count(root_certs) > 0 )
return x509_stores[root_certs];
X509_STORE* ctx = X509_STORE_new();
ListVal* idxs = root_certs->ConvertToPureList();
// Build the validation store
for ( int i = 0; i < idxs->Length(); ++i )
{
Val* key = idxs->Index(i);
StringVal *sv = root_certs->Lookup(key)->AsStringVal();
assert(sv);
const uint8_t* data = sv->Bytes();
X509* x = d2i_X509(NULL, &data, sv->Len());
if ( ! x )
{
builtin_error(fmt("Root CA error: %s", ERR_error_string(ERR_get_error(),NULL)));
return 0;
}
X509_STORE_add_cert(ctx, x);
X509_free(x);
}
delete idxs;
// Save the newly constructed certificate store into the cacheing map.
x509_stores[root_certs] = ctx;
return ctx;
}
// get all cretificates starting at the second one (assuming the first one is the host certificate) // get all cretificates starting at the second one (assuming the first one is the host certificate)
STACK_OF(X509)* x509_get_untrusted_stack(VectorVal* certs_vec) STACK_OF(X509)* x509_get_untrusted_stack(VectorVal* certs_vec)
{ {
@ -254,7 +216,7 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F
function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result function x509_ocsp_verify%(certs: x509_opaque_vector, ocsp_reply: string, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result
%{ %{
RecordVal* rval = 0; RecordVal* rval = 0;
X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal()); X509_STORE* ctx = ::file_analysis::X509::GetRootStore(root_certs->AsTableVal());
if ( ! ctx ) if ( ! ctx )
return x509_result_record(-1, "Problem initializing root store"); return x509_result_record(-1, "Problem initializing root store");
@ -540,7 +502,7 @@ x509_ocsp_cleanup:
## x509_get_certificate_string x509_ocsp_verify sct_verify ## x509_get_certificate_string x509_ocsp_verify sct_verify
function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_string, verify_time: time &default=network_time()%): X509::Result
%{ %{
X509_STORE* ctx = x509_get_root_store(root_certs->AsTableVal()); X509_STORE* ctx = ::file_analysis::X509::GetRootStore(root_certs->AsTableVal());
if ( ! ctx ) if ( ! ctx )
return x509_result_record(-1, "Problem initializing root store"); return x509_result_record(-1, "Problem initializing root store");

View file

@ -444,6 +444,7 @@ bool Manager::CreateEventStream(RecordVal* fval)
if ( status ) if ( status )
{ {
reporter->Error("Input stream %s: Problem unrolling", stream_name.c_str()); reporter->Error("Input stream %s: Problem unrolling", stream_name.c_str());
for ( auto& f : fieldsV ) delete f;
return false; return false;
} }
@ -453,6 +454,7 @@ bool Manager::CreateEventStream(RecordVal* fval)
if ( ! res ) if ( ! res )
{ {
delete stream; delete stream;
for ( auto& f : fieldsV ) delete f;
return false; return false;
} }
@ -671,6 +673,7 @@ bool Manager::CreateTableStream(RecordVal* fval)
if ( (valfields > 1) && (want_record->InternalInt() != 1) ) if ( (valfields > 1) && (want_record->InternalInt() != 1) )
{ {
reporter->Error("Input stream %s: Stream does not want a record (want_record=F), but has more then one value field.", stream_name.c_str()); reporter->Error("Input stream %s: Stream does not want a record (want_record=F), but has more then one value field.", stream_name.c_str());
for ( auto& f : fieldsV ) delete f;
return false; return false;
} }
@ -680,6 +683,7 @@ bool Manager::CreateTableStream(RecordVal* fval)
if ( status ) if ( status )
{ {
reporter->Error("Input stream %s: Problem unrolling", stream_name.c_str()); reporter->Error("Input stream %s: Problem unrolling", stream_name.c_str());
for ( auto& f : fieldsV ) delete f;
return false; return false;
} }
@ -689,6 +693,7 @@ bool Manager::CreateTableStream(RecordVal* fval)
if ( ! res ) if ( ! res )
{ {
delete stream; delete stream;
for ( auto& f : fieldsV ) delete f;
return false; return false;
} }
} }
@ -1289,7 +1294,8 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
if ( predidx != 0 ) if ( predidx != 0 )
Unref(predidx); Unref(predidx);
stream->currDict->Insert(idxhash, ih); auto prev = stream->currDict->Insert(idxhash, ih);
delete prev;
delete idxhash; delete idxhash;
if ( stream->event ) if ( stream->event )

View file

@ -49,6 +49,9 @@ SQLite::~SQLite()
void SQLite::DoClose() void SQLite::DoClose()
{ {
sqlite3_finalize(st);
st = nullptr;
if ( db != 0 ) if ( db != 0 )
{ {
sqlite3_close(db); sqlite3_close(db);

View file

@ -98,6 +98,7 @@ Manager::Filter::~Filter()
free(fields); free(fields);
Unref(path_val); Unref(path_val);
Unref(config);
} }
Manager::Stream::~Stream() Manager::Stream::~Stream()
@ -919,6 +920,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns)
filter->fields, vals), filter->fields, vals),
true) ) true) )
{ {
Unref(columns);
DeleteVals(filter->num_fields, vals); DeleteVals(filter->num_fields, vals);
#ifdef DEBUG #ifdef DEBUG

View file

@ -133,6 +133,11 @@ WriterFrontend::WriterFrontend(const WriterBackend::WriterInfo& arg_info, EnumVa
WriterFrontend::~WriterFrontend() WriterFrontend::~WriterFrontend()
{ {
for ( auto i = 0; i < num_fields; ++i )
delete fields[i];
delete [] fields;
Unref(stream); Unref(stream);
Unref(writer); Unref(writer);
delete info; delete info;
@ -165,7 +170,14 @@ void WriterFrontend::Init(int arg_num_fields, const Field* const * arg_fields)
initialized = true; initialized = true;
if ( backend ) if ( backend )
backend->SendIn(new InitMessage(backend, arg_num_fields, arg_fields)); {
auto fs = new Field*[num_fields];
for ( auto i = 0; i < num_fields; ++i )
fs[i] = new Field(*fields[i]);
backend->SendIn(new InitMessage(backend, arg_num_fields, fs));
}
if ( remote ) if ( remote )
{ {

View file

@ -308,6 +308,8 @@ void done_with_network()
abort(); abort();
} }
#endif #endif
ZEEK_LSAN_DISABLE();
} }
void terminate_bro() void terminate_bro()
@ -341,6 +343,7 @@ void terminate_bro()
mgr.Drain(); mgr.Drain();
notifier::registry.Terminate();
log_mgr->Terminate(); log_mgr->Terminate();
input_mgr->Terminate(); input_mgr->Terminate();
thread_mgr->Terminate(); thread_mgr->Terminate();
@ -406,6 +409,7 @@ static void bro_new_handler()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
ZEEK_LSAN_DISABLE();
std::set_new_handler(bro_new_handler); std::set_new_handler(bro_new_handler);
// When running unit tests, the first argument on the command line must be // When running unit tests, the first argument on the command line must be
@ -1052,6 +1056,13 @@ int main(int argc, char** argv)
reporter->Warning("event handler never invoked: %s", handler.c_str()); reporter->Warning("event handler never invoked: %s", handler.c_str());
} }
// Enable LeakSanitizer before zeek_init() and even before executing
// top-level statements. Even though it's not bad if a leak happens only
// once at initialization, we have to assume that script-layer code causing
// such a leak can be placed in any arbitrary event handler and potentially
// cause more severe problems.
ZEEK_LSAN_ENABLE();
if ( stmts ) if ( stmts )
{ {
stmt_flow_type flow; stmt_flow_type flow;

View file

@ -1234,7 +1234,7 @@ anonymous_function:
// a lambda expression. // a lambda expression.
// Gather the ingredients for a BroFunc from the current scope // Gather the ingredients for a BroFunc from the current scope
std::unique_ptr<function_ingredients> ingredients = gather_function_ingredients(current_scope(), $5); auto ingredients = std::make_unique<function_ingredients>(current_scope(), $5);
id_list outer_ids = gather_outer_ids(pop_scope(), $5); id_list outer_ids = gather_outer_ids(pop_scope(), $5);
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids)); $$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));

View file

@ -432,7 +432,7 @@ New_Patricia (int maxbits)
*/ */
void void
Clear_Patricia (patricia_tree_t *patricia, void_fn_t func) Clear_Patricia (patricia_tree_t *patricia, data_fn_t func)
{ {
assert (patricia); assert (patricia);
if (patricia->head) { if (patricia->head) {
@ -476,7 +476,7 @@ Clear_Patricia (patricia_tree_t *patricia, void_fn_t func)
void void
Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func) Destroy_Patricia (patricia_tree_t *patricia, data_fn_t func)
{ {
Clear_Patricia (patricia, func); Clear_Patricia (patricia, func);
Delete (patricia); Delete (patricia);
@ -489,7 +489,7 @@ Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func)
*/ */
void void
patricia_process (patricia_tree_t *patricia, void_fn_t func) patricia_process (patricia_tree_t *patricia, prefix_data_fn_t func)
{ {
patricia_node_t *node; patricia_node_t *node;
assert (func); assert (func);

View file

@ -51,8 +51,6 @@
#include <sys/types.h> #include <sys/types.h>
/* typedef unsigned int u_int; */
typedef void (*void_fn_t)();
/* { from defs.h */ /* { from defs.h */
#define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) #define prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin)
#define MAXLINE 1024 #define MAXLINE 1024
@ -84,6 +82,9 @@ typedef struct _prefix_t {
} add; } add;
} prefix_t; } prefix_t;
typedef void (*data_fn_t)(void*);
typedef void (*prefix_data_fn_t)(prefix_t*, void*);
/* } */ /* } */
typedef struct _patricia_node_t { typedef struct _patricia_node_t {
@ -110,9 +111,9 @@ patricia_node_t * patricia_search_best2 (patricia_tree_t *patricia, prefix_t *pr
patricia_node_t *patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix); patricia_node_t *patricia_lookup (patricia_tree_t *patricia, prefix_t *prefix);
void patricia_remove (patricia_tree_t *patricia, patricia_node_t *node); void patricia_remove (patricia_tree_t *patricia, patricia_node_t *node);
patricia_tree_t *New_Patricia (int maxbits); patricia_tree_t *New_Patricia (int maxbits);
void Clear_Patricia (patricia_tree_t *patricia, void_fn_t func); void Clear_Patricia (patricia_tree_t *patricia, data_fn_t func);
void Destroy_Patricia (patricia_tree_t *patricia, void_fn_t func); void Destroy_Patricia (patricia_tree_t *patricia, data_fn_t func);
void patricia_process (patricia_tree_t *patricia, void_fn_t func); void patricia_process (patricia_tree_t *patricia, prefix_data_fn_t func);
void Deref_Prefix (prefix_t * prefix); void Deref_Prefix (prefix_t * prefix);

View file

@ -156,7 +156,8 @@ function Reporter::get_weird_sampling_whitelist%(%): string_set
TableVal* set = new TableVal(string_set); TableVal* set = new TableVal(string_set);
for ( auto el : reporter->GetWeirdSamplingWhitelist() ) for ( auto el : reporter->GetWeirdSamplingWhitelist() )
{ {
set->Assign(new StringVal(el), nullptr); auto idx = make_intrusive<StringVal>(el);
set->Assign(idx.get(), nullptr);
} }
return set; return set;
%} %}

View file

@ -176,6 +176,7 @@ MsgThread::MsgThread() : BasicThread(), queue_in(this, 0), queue_out(0, this)
cnt_sent_in = cnt_sent_out = 0; cnt_sent_in = cnt_sent_out = 0;
main_finished = false; main_finished = false;
child_finished = false; child_finished = false;
child_sent_finish = false;
failed = false; failed = false;
thread_mgr->AddMsgThread(this); thread_mgr->AddMsgThread(this);
} }
@ -185,9 +186,10 @@ extern int signal_val;
void MsgThread::OnSignalStop() void MsgThread::OnSignalStop()
{ {
if ( main_finished || Killed() ) if ( main_finished || Killed() || child_sent_finish )
return; return;
child_sent_finish = true;
// Signal thread to terminate. // Signal thread to terminate.
SendIn(new FinishMessage(this, network_time), true); SendIn(new FinishMessage(this, network_time), true);
} }
@ -258,6 +260,9 @@ void MsgThread::OnKill()
void MsgThread::Heartbeat() void MsgThread::Heartbeat()
{ {
if ( child_sent_finish )
return;
SendIn(new HeartbeatMessage(this, network_time, current_time())); SendIn(new HeartbeatMessage(this, network_time, current_time()));
} }

View file

@ -306,6 +306,7 @@ private:
bool main_finished; // Main thread is finished, meaning child_finished propagated back through message queue. bool main_finished; // Main thread is finished, meaning child_finished propagated back through message queue.
bool child_finished; // Child thread is finished. bool child_finished; // Child thread is finished.
bool child_sent_finish; // Child thread asked to be finished.
bool failed; // Set to true when a command failed. bool failed; // Set to true when a command failed.
}; };

View file

@ -397,7 +397,7 @@ function terminate%(%): bool
// is false). // is false).
static bool prepare_environment(TableVal* tbl, bool set) static bool prepare_environment(TableVal* tbl, bool set)
{ {
ListVal* idxs = tbl->ConvertToPureList(); IntrusivePtr<ListVal> idxs{tbl->ConvertToPureList(), false};
for ( int i = 0; i < idxs->Length(); ++i ) for ( int i = 0; i < idxs->Length(); ++i )
{ {

View file

@ -1,5 +1,5 @@
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 6: division by zero (a / b) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 6: division by zero (a / b)
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 11: division by zero (a / b) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 11: division by zero (a / b)
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 16: division by zero (a / b) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 16: division by zero (a / b)
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 21: modulo by zero (a % b) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 22: modulo by zero (a % b)
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 26: modulo by zero (a % b) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.div-by-zero/div-by-zero.zeek, line 27: modulo by zero (a % b)

View file

@ -6,13 +6,13 @@
#open 2011-03-18-19-06-08 #open 2011-03-18-19-06-08
#fields ts level message location #fields ts level message location
#types time enum string string #types time enum string string
1300475168.783842 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.783842 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.915940 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.915940 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.916118 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.916118 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.918295 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.918295 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.952193 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.952193 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.952228 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.952228 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.954761 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.954761 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475168.962628 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475168.962628 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
1300475169.780331 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 10 1300475169.780331 Reporter::ERROR field value missing (c$ftp) /da/home/robin/bro/master/testing/btest/.tmp/core.expr-exception/expr-exception.zeek, line 11
#close 2011-03-18-19-06-13 #close 2011-03-18-19-06-13

View file

@ -1,12 +0,0 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path metrics
#open 2012-07-20-01-50-41
#fields ts metric_id filter_name index.host index.str index.network value
#types time enum string addr string subnet count
1342749041.601712 TEST_METRIC foo-bar 6.5.4.3 - - 4
1342749041.601712 TEST_METRIC foo-bar 7.2.1.5 - - 2
1342749041.601712 TEST_METRIC foo-bar 1.2.3.4 - - 6
#close 2012-07-20-01-50-49

View file

@ -1,24 +0,0 @@
----
clone, one, Broker::SUCCESS, [data=broker::data{110}]
clone, two, Broker::SUCCESS, [data=broker::data{223}]
clone, [1, 2], Broker::SUCCESS, [data=broker::data{1947/tcp}]
clone, three, Broker::FAILURE, [data=<uninitialized>]
clone, four, Broker::FAILURE, [data=<uninitialized>]
clone, five, Broker::FAILURE, [data=<uninitialized>]
clone, six, Broker::FAILURE, [data=<uninitialized>]
----
clone, one, Broker::SUCCESS, [data=broker::data{110}]
clone, two, Broker::SUCCESS, [data=broker::data{223}]
clone, [1, 2], Broker::SUCCESS, [data=broker::data{1947/tcp}]
clone, three, Broker::SUCCESS, [data=broker::data{3.140000}]
clone, four, Broker::SUCCESS, [data=broker::data{1.2.3.4}]
clone, five, Broker::FAILURE, [data=<uninitialized>]
clone, six, Broker::FAILURE, [data=<uninitialized>]
----
clone, one, Broker::SUCCESS, [data=broker::data{110}]
clone, two, Broker::SUCCESS, [data=broker::data{223}]
clone, [1, 2], Broker::SUCCESS, [data=broker::data{1947/tcp}]
clone, three, Broker::SUCCESS, [data=broker::data{3.140000}]
clone, four, Broker::FAILURE, [data=<uninitialized>]
clone, five, Broker::SUCCESS, [data=broker::data{555}]
clone, six, Broker::SUCCESS, [data=broker::data{666}]

View file

@ -1,120 +0,0 @@
Broker::BOOL
Broker::INT
Broker::COUNT
Broker::DOUBLE
Broker::STRING
Broker::ADDR
Broker::SUBNET
Broker::PORT
Broker::TIME
Broker::INTERVAL
Broker::ENUM
Broker::SET
Broker::TABLE
Broker::VECTOR
Broker::VECTOR
***************************
T
F
1
0
-1
1
0
1.1
-11.1
hello
1.2.3.4
192.168.0.0/16
22/tcp
42.0
180.0
Broker::BOOL
{
two,
one,
three
}
{
[two] = 2,
[one] = 1,
[three] = 3
}
[zero, one, two]
[a=<uninitialized>, b=bee, c=1]
[a=test, b=bee, c=1]
[a=test, b=testagain, c=1]
***************************
0
T
1
T
F
T
2
F
2
T
1
F
{
bye
}
T
0
{
}
***************************
0
[data=<uninitialized>]
1
T
42
F
[data=<uninitialized>]
2
[data=broker::data{7}]
2
37
[data=broker::data{42}]
1
[data=<uninitialized>]
1
T
0
{
}
***************************
0
T
T
T
T
[hi, salutations, hello, greetings]
4
[data=broker::data{hello}]
[data=broker::data{bah}]
[data=broker::data{hi}]
[hi, salutations, bah, greetings]
[data=broker::data{bah}]
[hi, salutations, greetings]
3
T
0
[]
***************************
3
T
T
T
[data=broker::data{hi}]
[data=broker::data{hello}]
[data=broker::data{37}]
3
T
3
[data=broker::data{goodbye}]
***************************
T

View file

@ -1,6 +0,0 @@
got event msg, ping, 0
got event msg, ping, 1
got event msg, ping, 2
got event msg, ping, 3
got event msg, ping, 4
got event msg, ping, 5

View file

@ -1,11 +0,0 @@
Broker peer added, 127.0.0.1
got event msg, pong, 0
got auto event msg, ping, 0
got event msg, pong, 1
got auto event msg, ping, 1
got event msg, pong, 2
got auto event msg, ping, 2
got event msg, pong, 3
got auto event msg, ping, 3
got event msg, pong, 4
got auto event msg, ping, 4

View file

@ -1,15 +0,0 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path test
#open 2017-04-26-01-04-25
#fields msg num
#types string count
ping 0
ping 1
ping 2
ping 3
ping 4
ping 5
#close 2017-04-26-01-04-26

View file

@ -1 +0,0 @@
Broker peer added, 127.0.0.1

View file

@ -1,15 +0,0 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path test
#open 2017-04-26-01-04-25
#fields msg num
#types string count
ping 0
ping 1
ping 2
ping 3
ping 4
ping 5
#close 2017-04-26-01-04-26

View file

@ -1,26 +0,0 @@
hello :-)
peer added
receiver got ping: function 2
inside: 1 | outside: 11 | global: 100
77
receiver got ping: function 1
begin: 100 | base_step: 2
begin: 100 | base_step: 2 | step: 76
178
receiver got ping: function 2
inside: 3 | outside: 11 | global: 100
79
receiver got ping: function 1
begin: 100 | base_step: 4
begin: 100 | base_step: 4 | step: 76
180
receiver got ping: function 2
inside: 5 | outside: 11 | global: 100
81
receiver got ping: function 1
begin: 100 | base_step: 6
begin: 100 | base_step: 6 | step: 76
182
receiver got ping: function 2
inside: 7 | outside: 11 | global: 100
83

View file

@ -1,31 +0,0 @@
hello :)
peer added
begin: 100 | base_step: 50
sender got pong: function 2
inside: 1 | outside: 11 | global: 10
77
begin: 100 | base_step: 50
sender got pong: function 1
begin: 178 | base_step: 2
begin: 178 | base_step: 2 | step: 76
256
begin: 100 | base_step: 50
sender got pong: function 2
inside: 3 | outside: 11 | global: 10
79
begin: 100 | base_step: 50
sender got pong: function 1
begin: 180 | base_step: 4
begin: 180 | base_step: 4 | step: 76
260
begin: 100 | base_step: 50
sender got pong: function 2
inside: 5 | outside: 11 | global: 10
81
begin: 100 | base_step: 50
sender got pong: function 1
begin: 182 | base_step: 6
begin: 182 | base_step: 6 | step: 76
264
begin: 100 | base_step: 50
peer lost

View file

@ -1,3 +1,3 @@
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.reporter-error-in-handler/reporter-error-in-handler.zeek, line 28: no such index (a[1]) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.reporter-error-in-handler/reporter-error-in-handler.zeek, line 29: no such index (a[1])
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.reporter-error-in-handler/reporter-error-in-handler.zeek, line 22: no such index (a[2]) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/core.reporter-error-in-handler/reporter-error-in-handler.zeek, line 23: no such index (a[2])
1st error printed on script level 1st error printed on script level

View file

@ -1,7 +1,7 @@
expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 47: field value missing (myrecord$notset) expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 48: field value missing (myrecord$notset)
expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 91: field value missing (myrecord$notset) expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 92: field value missing (myrecord$notset)
expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 72: field value missing (myrecord$notset) expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 73: field value missing (myrecord$notset)
expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 103: field value missing (myrecord$notset) expression error in /Users/jon/Projects/bro/bro/testing/btest/.tmp/core.when-interpreter-exceptions/when-interpreter-exceptions.zeek, line 104: field value missing (myrecord$notset)
received termination signal received termination signal
[f(F)] [f(F)]
f() done, no exception, T f() done, no exception, T

View file

@ -1,2 +1,2 @@
expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-expr-error/expire-expr-error.zeek, line 8: no such index (x[kaputt]) expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-expr-error/expire-expr-error.zeek, line 9: no such index (x[kaputt])
received termination signal received termination signal

View file

@ -1,20 +1,20 @@
1299470395.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299470395.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299470405.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299470405.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299473995.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299473995.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299474005.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299474005.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299477595.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299477595.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299477605.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299477605.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299481195.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299481195.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299481205.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299481205.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299484795.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299484795.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299484805.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299484805.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299488395.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299488395.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299488405.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299488405.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299491995.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299491995.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299492005.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299492005.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299495595.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299495595.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299495605.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299495605.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299499195.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299499195.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299499205.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299499205.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
1299502795.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 12: value used but not set (segfault::scan_summary) 1299502795.000000 expression error in /home/robin/bro/master/testing/btest/.tmp/language.expire-func-undef/expire-func-undef.zeek, line 13: value used but not set (segfault::scan_summary)
orig: 10.0.0.2: peers: {\x0a\x0910.0.0.3\x0a} orig: 10.0.0.2: peers: {\x0a\x0910.0.0.3\x0a}

View file

@ -1,5 +1,5 @@
runtime error in /home/jon/pro/zeek/zeek/scripts/base/utils/queue.zeek, line 152: vector index assignment failed for invalid type 'myrec', value: [a=T, b=hi, c=<uninitialized>], expression: Queue::ret[Queue::j], call stack: runtime error in /home/jon/pro/zeek/zeek/scripts/base/utils/queue.zeek, line 152: vector index assignment failed for invalid type 'myrec', value: [a=T, b=hi, c=<uninitialized>], expression: Queue::ret[Queue::j], call stack:
#0 Queue::get_vector([initialized=T, vals={[2] = test,[6] = jkl;,[4] = asdf,[1] = goodbye,[5] = 3,[0] = hello,[3] = [a=T, b=hi, c=<uninitialized>]}, settings=[max_len=<uninitialized>], top=7, bottom=0, size=0], [hello, goodbye, test]) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:19 #0 Queue::get_vector([initialized=T, vals={[2] = test,[6] = jkl;,[4] = asdf,[1] = goodbye,[5] = 3,[0] = hello,[3] = [a=T, b=hi, c=<uninitialized>]}, settings=[max_len=<uninitialized>], top=7, bottom=0, size=0], [hello, goodbye, test]) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:20
#1 bar(55) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:27 #1 bar(55) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:28
#2 foo(hi, 13) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:39 #2 foo(hi, 13) at /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.index-assignment-invalid/index-assignment-invalid.zeek:40
#3 zeek_init() #3 zeek_init()

View file

@ -1,5 +1,5 @@
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.invalid_index/invalid_index.zeek, line 10: no such index (foo[1]) expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.invalid_index/invalid_index.zeek, line 11: no such index (foo[1])
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.invalid_index/invalid_index.zeek, line 16: no such index (foo2[1]) expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.invalid_index/invalid_index.zeek, line 17: no such index (foo2[1])
foo[0], 42 foo[0], 42
foo2[0], 13 foo2[0], 13
done done

View file

@ -1,4 +1,4 @@
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 11: invalid cast of value with type 'count' to type 'string' (a as string) expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 12: invalid cast of value with type 'count' to type 'string' (a as string)
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 11: invalid cast of value with type 'record { a:addr; b:port; }' to type 'string' (a as string) expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 12: invalid cast of value with type 'record { a:addr; b:port; }' to type 'string' (a as string)
expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 11: invalid cast of value with type 'record { data:opaque of Broker::Data; }' to type 'string' (nil $data field) (a as string) expression error in /home/jon/pro/zeek/zeek/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.zeek, line 12: invalid cast of value with type 'record { data:opaque of Broker::Data; }' to type 'string' (nil $data field) (a as string)
data is string, F data is string, F

View file

@ -1,2 +1,2 @@
expression error in /home/jon/projects/bro/bro/testing/btest/.tmp/language.uninitialized-local2/uninitialized-local2.zeek, line 19: value used but not set (var_b) expression error in /home/jon/projects/bro/bro/testing/btest/.tmp/language.uninitialized-local2/uninitialized-local2.zeek, line 20: value used but not set (var_b)
var_a is, baz var_a is, baz

View file

@ -1,10 +1,10 @@
| Hook Some Info <...>/reporter-hook.zeek, line 16 | Hook Some Info <...>/reporter-hook.zeek, line 17
| Hook error An Error <...>/reporter-hook.zeek, line 18 | Hook error An Error <...>/reporter-hook.zeek, line 19
| Hook error An Error that does not show up in the log <...>/reporter-hook.zeek, line 19 | Hook error An Error that does not show up in the log <...>/reporter-hook.zeek, line 20
| Hook expression error field value missing (b$a) <...>/reporter-hook.zeek, line 23 | Hook expression error field value missing (b$a) <...>/reporter-hook.zeek, line 24
| Hook warning A warning <...>/reporter-hook.zeek, line 17 | Hook warning A warning <...>/reporter-hook.zeek, line 18
<...>/reporter-hook.zeek, line 16: Some Info <...>/reporter-hook.zeek, line 17: Some Info
error in <...>/reporter-hook.zeek, line 18: An Error error in <...>/reporter-hook.zeek, line 19: An Error
error in <...>/reporter-hook.zeek, line 19: An Error that does not show up in the log error in <...>/reporter-hook.zeek, line 20: An Error that does not show up in the log
expression error in <...>/reporter-hook.zeek, line 23: field value missing (b$a) expression error in <...>/reporter-hook.zeek, line 24: field value missing (b$a)
warning in <...>/reporter-hook.zeek, line 17: A warning warning in <...>/reporter-hook.zeek, line 18: A warning

View file

@ -6,8 +6,8 @@
#open 2017-07-26-17-58-52 #open 2017-07-26-17-58-52
#fields ts level message location #fields ts level message location
#types time enum string string #types time enum string string
0.000000 Reporter::INFO Some Info /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 16 0.000000 Reporter::INFO Some Info /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 17
0.000000 Reporter::WARNING A warning /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 17 0.000000 Reporter::WARNING A warning /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 18
0.000000 Reporter::ERROR An Error /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 18 0.000000 Reporter::ERROR An Error /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 19
0.000000 Reporter::ERROR field value missing (b$a) /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 23 0.000000 Reporter::ERROR field value missing (b$a) /Users/johanna/corelight/bro/testing/btest/.tmp/plugins.reporter-hook/reporter-hook.zeek, line 24
#close 2017-07-26-17-58-52 #close 2017-07-26-17-58-52

View file

@ -6,5 +6,5 @@
#open 2012-08-10-20-09-16 #open 2012-08-10-20-09-16
#fields ts level message location #fields ts level message location
#types time enum string string #types time enum string string
0.000000 Reporter::ERROR no such index (test[3]) /da/home/robin/bro/master/testing/btest/.tmp/scripts.base.frameworks.reporter.disable-stderr/disable-stderr.zeek, line 12 0.000000 Reporter::ERROR no such index (test[3]) /da/home/robin/bro/master/testing/btest/.tmp/scripts.base.frameworks.reporter.disable-stderr/disable-stderr.zeek, line 13
#close 2012-08-10-20-09-16 #close 2012-08-10-20-09-16

View file

@ -1 +1 @@
expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/scripts.base.frameworks.reporter.stderr/stderr.zeek, line 9: no such index (test[3]) expression error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/scripts.base.frameworks.reporter.stderr/stderr.zeek, line 10: no such index (test[3])

View file

@ -6,5 +6,5 @@
#open 2013-01-18-18-29-30 #open 2013-01-18-18-29-30
#fields ts level message location #fields ts level message location
#types time enum string string #types time enum string string
0.000000 Reporter::ERROR no such index (test[3]) /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/scripts.base.frameworks.reporter.stderr/stderr.zeek, line 9 0.000000 Reporter::ERROR no such index (test[3]) /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/scripts.base.frameworks.reporter.stderr/stderr.zeek, line 10
#close 2013-01-18-18-29-30 #close 2013-01-18-18-29-30

View file

@ -0,0 +1,58 @@
irc_names_info, #easymovies, {
WhatmeWor,
starred,
fvlkni,
NeverServe,
zgdB8_VzO,
+TrEeHoUsE,
zEmm,
dezmond411,
mikejo1,
freeeman33,
aJerk,
+Luccutis,
jafafar,
|EasyMovie|,
cguide,
skillZ,
+i-am-mojo,
mo5,
+Xedrethor,
kitts,
macbeth420,
Picard,
`Xenu,
+gordon1`^,
N2Oblivion,
scum,
bloed,
katniss,
GordonCamero,
+Max_Renn,
mzazzali,
Verge,
bouleemil,
eag,
+`AngelnTx,
+Killazherb,
gasman2,
HagBard,
wanker,
habzels,
ericdraven,
nofire,
+thenagualII,
bga,
friida,
+ladyvampress,
tonysaunt,
Peebo,
slickrick2
}
irc_names_info, #easymovies, {
dx3d51,
TinCan,
Nachos,
Latika,
TooFast
}

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path conn
#open 2020-01-01-22-01-07
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string]
1331918844.980000 CHhAvVGS1DHFjwGM9 192.168.202.110 43792 192.168.229.251 88 tcp krb_tcp 0.010000 110 90 S1 - - 0 ^hADd 2 214 2 206 -
#close 2020-01-01-22-01-07

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path kerberos
#open 2020-01-01-22-01-07
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p request_type client service success error_msg from till cipher forwardable renewable client_cert_subject client_cert_fuid server_cert_subject server_cert_fuid
#types time string addr port addr port string string string bool string time time string bool bool string string string string
1331918844.990000 CHhAvVGS1DHFjwGM9 192.168.202.110 43792 192.168.229.251 88 AS /kerberos_realm_time.nasl krbtgt/HEC.NET F KRB_ERR_GENERIC - 2136422885.000000 - T F - - - -
#close 2020-01-01-22-01-07

View file

@ -1,17 +1,12 @@
# Needs perftools support.
#
# @TEST-PORT: BROKER_PORT1 # @TEST-PORT: BROKER_PORT1
# @TEST-PORT: BROKER_PORT2 # @TEST-PORT: BROKER_PORT2
# @TEST-PORT: BROKER_PORT3 # @TEST-PORT: BROKER_PORT3
# @TEST-GROUP: leaks
# #
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks # @TEST-EXEC: zeek %INPUT>out
# # @TEST-EXEC: btest-bg-run manager-1 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=manager-1 zeek %INPUT
# @TEST-EXEC: zeek -m %INPUT>out # @TEST-EXEC: btest-bg-run worker-1 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-1 zeek runnumber=1 %INPUT
# @TEST-EXEC: btest-bg-run manager-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=manager-1 zeek -m %INPUT # @TEST-EXEC: btest-bg-run worker-2 ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-2 zeek runnumber=2 %INPUT
# @TEST-EXEC: btest-bg-run worker-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-1 zeek -m runnumber=1 %INPUT # @TEST-EXEC: btest-bg-wait 30
# @TEST-EXEC: btest-bg-run worker-2 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-2 zeek -m runnumber=2 %INPUT
# @TEST-EXEC: btest-bg-wait 120
# #
# @TEST-EXEC: btest-diff manager-1/.stdout # @TEST-EXEC: btest-diff manager-1/.stdout
# @TEST-EXEC: btest-diff worker-1/.stdout # @TEST-EXEC: btest-diff worker-1/.stdout

View file

@ -1,4 +1,5 @@
# @TEST-EXEC: zeek -b %INPUT >out 2>&1 # TODO: interpreter exceptions currently may cause memory leaks, so disable leak checks
# @TEST-EXEC: ASAN_OPTIONS="detect_leaks=0" zeek -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
event div_int(a: int, b: int) event div_int(a: int, b: int)

View file

@ -1,7 +1,8 @@
# Expressions in an event handler that raise interpreter exceptions # Expressions in an event handler that raise interpreter exceptions
# shouldn't abort Zeek entirely, but just return from the function body. # shouldn't abort Zeek entirely, but just return from the function body.
# #
# @TEST-EXEC: zeek -r $TRACES/wikipedia.trace %INPUT >output # TODO: interpreter exceptions currently may cause memory leaks, so disable leak checks
# @TEST-EXEC: ASAN_OPTIONS="detect_leaks=0" zeek -r $TRACES/wikipedia.trace %INPUT >output
# @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff reporter.log # @TEST-EXEC: TEST_DIFF_CANONIFIER="$SCRIPTS/diff-remove-abspath | $SCRIPTS/diff-remove-timestamps" btest-diff reporter.log
# @TEST-EXEC: btest-diff output # @TEST-EXEC: btest-diff output

View file

@ -1,8 +0,0 @@
# Needs perftools support.
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-GROUP: leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -r $TRACES/tunnels/ayiya3.trace
# @TEST-EXEC: btest-bg-wait 90

View file

@ -1,90 +0,0 @@
# Needs perftools support.
#
# @TEST-PORT: BROKER_PORT1
# @TEST-PORT: BROKER_PORT2
# @TEST-PORT: BROKER_PORT3
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: btest-bg-run manager-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=manager-1 zeek -m %INPUT
# @TEST-EXEC: btest-bg-run worker-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-1 zeek -m %INPUT
# @TEST-EXEC: btest-bg-run worker-2 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local ZEEKPATH=$ZEEKPATH:.. CLUSTER_NODE=worker-2 zeek -m %INPUT
# @TEST-EXEC: btest-bg-wait 120
@TEST-START-FILE cluster-layout.zeek
redef Cluster::nodes = {
["manager-1"] = [$node_type=Cluster::MANAGER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT1"))],
["worker-1"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT2")), $manager="manager-1", $interface="eth0"],
["worker-2"] = [$node_type=Cluster::WORKER, $ip=127.0.0.1, $p=to_port(getenv("BROKER_PORT3")), $manager="manager-1", $interface="eth1"],
};
@TEST-END-FILE
redef Log::default_rotation_interval = 0secs;
global n = 0;
event zeek_init() &priority=5
{
local r1: SumStats::Reducer = [$stream="test", $apply=set(SumStats::SUM, SumStats::MIN, SumStats::MAX, SumStats::AVERAGE, SumStats::STD_DEV, SumStats::VARIANCE, SumStats::UNIQUE)];
SumStats::create([$name="test",
$epoch=5secs,
$reducers=set(r1),
$epoch_result(ts: time, key: SumStats::Key, result: SumStats::Result) =
{
local r = result["test"];
print fmt("Host: %s - num:%d - sum:%.1f - avg:%.1f - max:%.1f - min:%.1f - var:%.1f - std_dev:%.1f - unique:%d", key$host, r$num, r$sum, r$average, r$max, r$min, r$variance, r$std_dev, r$unique);
},
$epoch_finished(ts: time) =
{
terminate();
}]);
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
global ready_for_data: event();
event zeek_init()
{
Broker::auto_publish(Cluster::worker_topic, ready_for_data);
}
event ready_for_data()
{
if ( Cluster::node == "worker-1" )
{
SumStats::observe("test", [$host=1.2.3.4], [$num=34]);
SumStats::observe("test", [$host=1.2.3.4], [$num=30]);
SumStats::observe("test", [$host=6.5.4.3], [$num=1]);
SumStats::observe("test", [$host=7.2.1.5], [$num=54]);
}
if ( Cluster::node == "worker-2" )
{
SumStats::observe("test", [$host=1.2.3.4], [$num=75]);
SumStats::observe("test", [$host=1.2.3.4], [$num=30]);
SumStats::observe("test", [$host=1.2.3.4], [$num=3]);
SumStats::observe("test", [$host=1.2.3.4], [$num=57]);
SumStats::observe("test", [$host=1.2.3.4], [$num=52]);
SumStats::observe("test", [$host=1.2.3.4], [$num=61]);
SumStats::observe("test", [$host=1.2.3.4], [$num=95]);
SumStats::observe("test", [$host=6.5.4.3], [$num=5]);
SumStats::observe("test", [$host=7.2.1.5], [$num=91]);
SumStats::observe("test", [$host=10.10.10.10], [$num=5]);
}
}
@if ( Cluster::local_node_type() == Cluster::MANAGER )
global peer_count = 0;
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
++peer_count;
if ( peer_count == 2 )
event ready_for_data();
}
@endif

View file

@ -1,101 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b -r $TRACES/wikipedia.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
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();
}

View file

@ -1,144 +0,0 @@
# @TEST-PORT: BROKER_PORT
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run clone "zeek -m -b ../clone.zeek >clone.out"
# @TEST-EXEC: btest-bg-run master "zeek -b ../master.zeek >master.out"
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff clone/clone.out
@TEST-START-FILE master.zeek
redef exit_only_after_terminate = T;
global query_timeout = 1sec;
global ready: event();
global h: opaque of Broker::Store;
function print_index(k: any)
{
when ( local r = Broker::get(h, k) )
{
print "master", k, r$status, r$result;
}
timeout query_timeout
{
print "master", fmt("clone <timeout for %s>", k);
}
}
event done()
{
terminate();
}
event inserted()
{
Broker::erase(h, "four");
print("----");
print_index("one");
print_index("two");
print_index(vector(1,2));
print_index("three");
print_index("four");
print_index("five");
print_index("six");
schedule 2secs { done() };
}
event zeek_init()
{
Broker::auto_publish("bro/events", done);
Broker::subscribe("bro/");
h = Broker::create_master("test");
Broker::put(h, "one", "110");
Broker::put(h, "two", 223);
Broker::put(h, vector(1,2), 1947/tcp);
Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
event insert_more()
{
Broker::put(h, "three", 3.14);
Broker::put(h, "four", 1.2.3.4);
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
schedule 4secs { insert_more() };
}
@TEST-END-FILE
@TEST-START-FILE clone.zeek
redef exit_only_after_terminate = T;
global query_timeout = 1sec;
global h: opaque of Broker::Store;
global inserted: event();
function print_index(k: any)
{
when ( local r = Broker::get(h, k) )
{
print "clone", k, r$status, r$result;
}
timeout query_timeout
{
print "clone", fmt("clone <timeout for %s>", k);
}
}
event lookup(stage: count)
{
print("----");
print_index("one");
print_index("two");
print_index(vector(1,2));
print_index("three");
print_index("four");
print_index("five");
print_index("six");
if ( stage == 1 )
schedule 4secs { lookup(2) };
if ( stage == 2 )
{
Broker::put(h, "five", "555");
Broker::put(h, "six", "666");
event inserted();
schedule 2secs { lookup(3) };
}
}
event done()
{
terminate();
}
event zeek_init()
{
Broker::auto_publish("bro/events", inserted);
Broker::subscribe("bro/");
Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
h = Broker::create_clone("test");
schedule 2secs { lookup(1) };
}
@TEST-END-FILE

View file

@ -1,270 +0,0 @@
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b -r $TRACES/http/get.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: btest-diff zeek/.stdout
type bro_set: set[string];
type bro_table: table[string] of count;
type bro_vector: vector of string;
type bro_record : record {
a: string &optional;
b: string &default = "bee";
c: count;
};
function broker_to_bro_record_recurse(it: opaque of Broker::RecordIterator,
rval: bro_record,
idx: count): bro_record
{
if ( Broker::record_iterator_last(it) )
return rval;
local field_value = Broker::record_iterator_value(it);
if ( field_value?$data )
switch ( idx ) {
case 0:
rval$a = field_value as string;
break;
case 1:
rval$b = field_value as string;
break;
case 2:
rval$c = field_value as count;
break;
};
++idx;
Broker::record_iterator_next(it);
return broker_to_bro_record_recurse(it, rval, idx);
}
function broker_to_bro_record(d: Broker::Data): bro_record
{
return broker_to_bro_record_recurse(Broker::record_iterator(d),
bro_record($c = 0), 0);
}
function
broker_to_bro_set_recurse(it: opaque of Broker::SetIterator,
rval: bro_set): bro_set
{
if ( Broker::set_iterator_last(it) )
return rval;
add rval[Broker::set_iterator_value(it) as string];
Broker::set_iterator_next(it);
return broker_to_bro_set_recurse(it, rval);
}
function broker_to_bro_set(d: Broker::Data): bro_set
{
return broker_to_bro_set_recurse(Broker::set_iterator(d), bro_set());
}
function
broker_to_bro_table_recurse(it: opaque of Broker::TableIterator,
rval: bro_table): bro_table
{
if ( Broker::table_iterator_last(it) )
return rval;
local item = Broker::table_iterator_value(it);
rval[item$key as string] = item$val as count;
Broker::table_iterator_next(it);
return broker_to_bro_table_recurse(it, rval);
}
function broker_to_bro_table(d: Broker::Data): bro_table
{
return broker_to_bro_table_recurse(Broker::table_iterator(d),
bro_table());
}
function broker_to_bro_vector_recurse(it: opaque of Broker::VectorIterator,
rval: bro_vector): bro_vector
{
if ( Broker::vector_iterator_last(it) )
return rval;
rval += Broker::vector_iterator_value(it) as string;
Broker::vector_iterator_next(it);
return broker_to_bro_vector_recurse(it, rval);
}
function broker_to_bro_vector(d: Broker::Data): bro_vector
{
return broker_to_bro_vector_recurse(Broker::vector_iterator(d),
bro_vector());
}
global did_it = F;
event new_connection(c: connection)
{
if ( did_it ) return;
did_it = T;
### Print every Broker data type
print Broker::data_type(Broker::data(T));
print Broker::data_type(Broker::data(+1));
print Broker::data_type(Broker::data(1));
print Broker::data_type(Broker::data(1.1));
print Broker::data_type(Broker::data("1 (how creative)"));
print Broker::data_type(Broker::data(1.1.1.1));
print Broker::data_type(Broker::data(1.1.1.1/1));
print Broker::data_type(Broker::data(1/udp));
print Broker::data_type(Broker::data(double_to_time(1)));
print Broker::data_type(Broker::data(1sec));
print Broker::data_type(Broker::data(Broker::BOOL));
local s: bro_set = bro_set("one", "two", "three");
local t: bro_table = bro_table(["one"] = 1, ["two"] = 2, ["three"] = 3);
local v: bro_vector = bro_vector("zero", "one", "two");
local r: bro_record = bro_record($c = 1);
print Broker::data_type(Broker::data(s));
print Broker::data_type(Broker::data(t));
print Broker::data_type(Broker::data(v));
print Broker::data_type(Broker::data(r));
print "***************************";
### Convert a Zeek value to a Broker value, then print the result
print (Broker::data(T)) as bool;
print (Broker::data(F)) as bool;
print (Broker::data(+1)) as int;
print (Broker::data(+0)) as int;
print (Broker::data(-1)) as int;
print (Broker::data(1)) as count;
print (Broker::data(0)) as count;
print (Broker::data(1.1)) as double;
print (Broker::data(-11.1)) as double;
print (Broker::data("hello")) as string;
print (Broker::data(1.2.3.4)) as addr;
print (Broker::data(192.168.1.1/16)) as subnet;
print (Broker::data(22/tcp)) as port;
print (Broker::data(double_to_time(42))) as time;
print (Broker::data(3min)) as interval;
print (Broker::data(Broker::BOOL)) as Broker::DataType;
local cs = Broker::data(s);
print broker_to_bro_set(cs);
local ct = Broker::data(t);
print broker_to_bro_table(ct);
local cv = Broker::data(v);
print broker_to_bro_vector(cv);
local cr = Broker::data(r);
print broker_to_bro_record(cr);
r$a = "test";
cr = Broker::data(r);
print broker_to_bro_record(cr);
r$b = "testagain";
cr = Broker::data(r);
print broker_to_bro_record(cr);
print "***************************";
### Test the Broker set BIFs
cs = Broker::set_create();
print Broker::set_size(cs);
print Broker::set_insert(cs, ("hi"));
print Broker::set_size(cs);
print Broker::set_contains(cs, ("hi"));
print Broker::set_contains(cs, ("bye"));
print Broker::set_insert(cs, ("bye"));
print Broker::set_size(cs);
print Broker::set_insert(cs, ("bye"));
print Broker::set_size(cs);
print Broker::set_remove(cs, ("hi"));
print Broker::set_size(cs);
print Broker::set_remove(cs, ("hi"));
print broker_to_bro_set(cs);
print Broker::set_clear(cs);
print Broker::set_size(cs);
print broker_to_bro_set(cs);
print "***************************";
### Test the Broker table BIFs
ct = Broker::table_create();
print Broker::table_size(ct);
print Broker::table_insert(ct, ("hi"), (42));
print Broker::table_size(ct);
print Broker::table_contains(ct, ("hi"));
print (Broker::table_lookup(ct, ("hi"))) as count;
print Broker::table_contains(ct, ("bye"));
print Broker::table_insert(ct, ("bye"), (7));
print Broker::table_size(ct);
print Broker::table_insert(ct, ("bye"), (37));
print Broker::table_size(ct);
print (Broker::table_lookup(ct, ("bye"))) as count;
print Broker::table_remove(ct, ("hi"));
print Broker::table_size(ct);
print Broker::table_remove(ct, ("hi"));
print Broker::table_size(ct);
print Broker::table_clear(ct);
print Broker::table_size(ct);
print broker_to_bro_table(ct);
print "***************************";
### Test the Broker vector BIFs
cv = Broker::vector_create();
print Broker::vector_size(cv);
print Broker::vector_insert(cv, 0, ("hi"));
print Broker::vector_insert(cv, 1, ("hello"));
print Broker::vector_insert(cv, 2, ("greetings"));
print Broker::vector_insert(cv, 1, ("salutations"));
print broker_to_bro_vector(cv);
print Broker::vector_size(cv);
print Broker::vector_replace(cv, 2, ("bah"));
print Broker::vector_lookup(cv, 2);
print Broker::vector_lookup(cv, 0);
print broker_to_bro_vector(cv);
print Broker::vector_remove(cv, 2);
print broker_to_bro_vector(cv);
print Broker::vector_size(cv);
print Broker::vector_clear(cv);
print Broker::vector_size(cv);
print broker_to_bro_vector(cv);
print "***************************";
### Test the Broker record BIFs
cr = Broker::record_create(3);
print Broker::record_size(cr);
print Broker::record_assign(cr, 0, ("hi"));
print Broker::record_assign(cr, 1, ("hello"));
print Broker::record_assign(cr, 2, (37));
print Broker::record_lookup(cr, 0);
print Broker::record_lookup(cr, 1);
print Broker::record_lookup(cr, 2);
print Broker::record_size(cr);
print Broker::record_assign(cr, 1, ("goodbye"));
print Broker::record_size(cr);
print Broker::record_lookup(cr, 1);
print "***************************";
### Test an opaque value
local k1: opaque of topk = topk_init(4);
topk_add(k1, "a");
print Broker::data(k1) is opaque of topk;
Broker::data(k1) as opaque of topk;
}

View file

@ -1,149 +0,0 @@
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b -r $TRACES/http/get.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
redef exit_only_after_terminate = T;
global query_timeout = 45sec;
global h: opaque of Broker::Store;
global step: count = 0;
function print_index(k: any)
{
when ( local r = Broker::get(h, k) )
{
step += 1;
print fmt("[%d]", step), k, r$status, r$result;
}
timeout query_timeout
{
step += 1;
print fmt("[%d] <timeout for %s>", step, k);
}
}
function print_exists(k: any)
{
when ( local r = Broker::exists(h, k) )
{
step += 1;
print fmt("[%d]", step), k, r;
}
timeout query_timeout
{
step += 1;
print fmt("[%d] <timeout for %s>", step, k);
}
}
function print_index_from_value(k: any, i: any)
{
when ( local r = Broker::get_index_from_value(h, k, i) )
{
step += 1;
print fmt("[%d]", step), k, r$status, r$result;
}
timeout query_timeout
{
step += 1;
print fmt("[%d] <timeout for %s>", step, k);
}
}
function print_keys()
{
when ( local s = Broker::keys(h) )
{
step += 1;
print "keys", s;
}
timeout query_timeout
{
step += 1;
print fmt("[%d] <timeout for print keys>", step);
}
}
event done()
{
terminate();
}
event pk2()
{
print_keys();
}
event pk1()
{
print_keys();
Broker::clear(h);
schedule 1sec { pk2() };
}
event zeek_init()
{
h = Broker::create_master("master");
Broker::put(h, "one", "110");
Broker::put(h, "two", 220);
Broker::put(h, "three", 330);
Broker::put(h, "four", set(1, 2,3));
Broker::put(h, set("x", "y"), vector(1/tcp, 2/tcp, 3/tcp));
Broker::put(h, "str", "foo");
Broker::put(h, "vec", vector(1, 2,3));
Broker::put(h, "set", set("A", "B"));
Broker::put(h, "table", table(["a"] = 1, ["b"] = 2));
print_index("one");
print_index("two");
print_index("three");
print_index("four");
print_index("five");
print_index(set("x", "y"));
when ( step == 6 )
{
Broker::increment(h, "two");
Broker::increment(h, "two", 9);
Broker::decrement(h, "three");
Broker::decrement(h, "three", 9);
print_index("two");
print_index("three");
print_index("four");
print_keys();
Broker::erase(h, "four");
Broker::append(h, "str", "bar");
Broker::insert_into_set(h, "set", "C");
Broker::insert_into_table(h, "table", "c", 3);
Broker::remove_from(h, "set", 2);
Broker::remove_from(h, "table", "b");
Broker::push(h, "vec", 4);
Broker::push(h, "vec", 5);
Broker::pop(h, "vec");
print_index("str");
print_index("set");
print_index("table");
print_index("vec");
print_exists("one");
print_exists("NOPE");
print_index_from_value("vec", 1);
print_index_from_value("set", "A");
print_index_from_value("table", "a");
print_index_from_value("table", "X");
schedule 1sec { pk1() };
}
schedule 15secs { done() };
}

View file

@ -1,85 +0,0 @@
# @TEST-PORT: BROKER_PORT
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "zeek -m -b ../recv.zeek >recv.out"
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "zeek -m -b ../send.zeek >send.out"
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: btest-diff recv/recv.out
# @TEST-EXEC: btest-diff send/send.out
@TEST-START-FILE recv.zeek
redef exit_only_after_terminate = T;
global event_handler: event(msg: string, c: count);
global auto_event_handler: event(msg: string, c: count);
event zeek_init()
{
Broker::subscribe("bro/event/");
Broker::auto_publish("bro/event/my_topic", auto_event_handler);
Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
global event_count = 0;
global events_to_recv = 6;
event event_handler(msg: string, n: count)
{
++event_count;
print "got event msg", msg, n;
if ( event_count == events_to_recv )
{
terminate();
return;
}
event auto_event_handler(msg, n);
Broker::publish("bro/event/my_topic", event_handler, "pong", n);
}
@TEST-END-FILE
@TEST-START-FILE send.zeek
redef exit_only_after_terminate = T;
global event_handler: event(msg: string, c: count);
global auto_event_handler: event(msg: string, c: count);
event zeek_init()
{
Broker::subscribe("bro/event/my_topic");
Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT")), 1secs);
}
global event_count = 0;
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "Broker peer added", endpoint$network$address;
Broker::publish("bro/event/hi", event_handler, "ping", event_count);
++event_count;
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
event event_handler(msg: string, n: count)
{
print "got event msg", msg, n;
Broker::publish("bro/event/hi", event_handler, "ping", event_count);
++event_count;
}
event auto_event_handler(msg: string, n: count)
{
print "got auto event msg", msg, n;
}
@TEST-END-FILE

View file

@ -1,88 +0,0 @@
# @TEST-PORT: BROKER_PORT
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "zeek -m -b ../recv.zeek >recv.out"
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "zeek -m -b ../send.zeek >send.out"
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: btest-diff recv/recv.out
# @TEST-EXEC: btest-diff recv/test.log
# @TEST-EXEC: btest-diff send/send.out
# @TEST-EXEC: btest-diff send/test.log
@TEST-START-FILE common.zeek
redef exit_only_after_terminate = T;
module Test;
export {
redef enum Log::ID += { LOG };
type Info: record {
msg: string &log;
nolog: string &default="no";
num: count &log;
};
}
event zeek_init() &priority=5
{
Log::create_stream(Test::LOG, [$columns=Test::Info]);
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
@TEST-END-FILE
@TEST-START-FILE recv.zeek
@load ./common
event zeek_init()
{
Broker::subscribe("zeek/");
Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
event Broker::peer_removed(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
@TEST-END-FILE
@TEST-START-FILE send.zeek
@load ./common
event zeek_init()
{
Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
global n = 0;
event do_write()
{
if ( n == 6 )
terminate();
else
{
Log::write(Test::LOG, [$msg = "ping", $num = n]);
++n;
schedule 0.1secs { do_write() };
}
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "Broker peer added", endpoint$network$address;
event do_write();
}
@TEST-END-FILE

View file

@ -1,168 +0,0 @@
# @TEST-PORT: BROKER_PORT
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-GROUP: leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run recv "zeek -m -b ../recv.zeek >recv.out"
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run send "zeek -m -b ../send.zeek >send.out"
# @TEST-EXEC: btest-bg-wait 90
# @TEST-EXEC: btest-diff recv/recv.out
# @TEST-EXEC: btest-diff send/send.out
@TEST-START-FILE send.zeek
redef exit_only_after_terminate = T;
type myfunctype: function(c: count) : function(d: count) : count;
global global_with_same_name = 10;
global ping: event(msg: string, f: myfunctype);
event zeek_init()
{
print "hello :)";
Broker::subscribe("zeek/event/my_topic");
Broker::peer("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
global n = 0;
function send_event()
{
# in this frame event_count has an offset of three.
# in the receiving frame it has an offset of one.
# this tests to ensure that id lookups are being routed properly.
local dog = 0;
local not_dog = 1;
local event_count = 11;
local log : myfunctype = function(c: count) : function(d: count) : count
{
print fmt("inside: %s | outside: %s | global: %s", c, event_count, global_with_same_name);
return function(d: count) : count { return d + c; };
};
local two_part_adder_maker = function (begin : count) : function (base_step : count) : function ( step : count) : count
{
return function (base_step : count) : function (step : count) : count
{
print fmt("begin: %s | base_step: %s", begin, base_step);
return function (step : count) : count
{
print fmt("begin: %s | base_step: %s | step: %s", begin, base_step, step);
return (begin += base_step + step); }; }; };
local l = two_part_adder_maker(100);
local stepper = l(50);
++n;
if ( n % 2 == 0)
{
local e2 = Broker::make_event(ping, "function 1", l);
Broker::publish("zeek/event/my_topic", e2);
}
else
{
local e = Broker::make_event(ping, "function 2", log);
Broker::publish("zeek/event/my_topic", e);
}
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer added";
send_event();
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer lost";
terminate();
}
event pong(msg: string, f: myfunctype)
{
print fmt("sender got pong: %s", msg);
local adder = f(n);
print adder(76);
send_event();
}
@TEST-END-FILE
@TEST-START-FILE recv.zeek
redef exit_only_after_terminate = T;
const events_to_recv = 7;
type myfunctype: function(c: count) : function(d: count) : count;
# type myfunctype: function(c: count);
global global_with_same_name = 100;
global pong: event(msg: string, f: myfunctype);
# This is one, of many, ways to declare your functions that you plan to receive.
# All you are doing is giving the parser a version of their body, so they can be
# anywhere. This seems to work quite nicely because it keeps them scoped and stops
# them from ever being evaluated.
function my_funcs()
{
return;
local begin = 100;
local event_count = begin;
local l : myfunctype = function(c: count) : function(d: count) : count
{
print fmt("inside: %s | outside: %s | global: %s", c, event_count, global_with_same_name);
return function(d: count) : count { return d + c; };
};
local dog_fish = function (base_step : count) : function (step : count) : count
{
# actual formatting doesn't matter for name resolution.
print fmt("begin: %s | base_step: %s", begin, base_step);
return function (step : count) : count
{
print fmt("begin: %s | base_step: %s | step: %s", begin, base_step, step);
return (begin += base_step + step); }; };
}
event zeek_init()
{
print "hello :-)";
Broker::subscribe("zeek/event/my_topic");
Broker::listen("127.0.0.1", to_port(getenv("BROKER_PORT")));
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer added";
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
print "peer lost";
}
global n = 0;
event ping(msg: string, f: myfunctype)
{
print fmt("receiver got ping: %s", msg);
++n;
local adder = f(n);
print adder(76);
if ( n == events_to_recv )
{
terminate();
}
else
{
local e = Broker::make_event(pong, msg, f);
Broker::publish("zeek/event/my_topic", e);
}
}
@TEST-END-FILE

View file

@ -1,90 +0,0 @@
# @TEST-GROUP: leaks
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b -r $TRACES/wikipedia.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
global did_it = F;
event new_connection(c: connection)
{
if ( did_it )
return;
did_it = T;
print "============ Topk";
local k1: opaque of topk = topk_init(4);
topk_add(k1, "a");
topk_add(k1, "b");
topk_add(k1, "b");
topk_add(k1, "c");
local k2 = copy(k1);
print topk_get_top(k1, 5);
topk_add(k1, "shoulnotshowup");
print topk_get_top(k2, 5);
print "============ HLL";
local c1 = hll_cardinality_init(0.01, 0.95);
hll_cardinality_add(c1, 2001);
hll_cardinality_add(c1, 2002);
hll_cardinality_add(c1, 2003);
print hll_cardinality_estimate(c1);
local c2 = copy(c1);
hll_cardinality_add(c1, 2004);
print hll_cardinality_estimate(c2);
print "============ Bloom";
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);
local bf_copy = copy(bf_cnt);
bloomfilter_add(bf_cnt, 0);
print bloomfilter_lookup(bf_copy, 0);
print bloomfilter_lookup(bf_copy, 42);
# check that typefication transfered.
bloomfilter_add(bf_copy, 0.5); # causes stderr output
print "============ Hashes";
local md5a = md5_hash_init();
md5_hash_update(md5a, "one");
local md5b = copy(md5a);
md5_hash_update(md5a, "two");
md5_hash_update(md5b, "two");
print md5_hash_finish(md5a);
print md5_hash_finish(md5b);
local sha1a = sha1_hash_init();
sha1_hash_update(sha1a, "one");
local sha1b = copy(sha1a);
sha1_hash_update(sha1a, "two");
sha1_hash_update(sha1b, "two");
print sha1_hash_finish(sha1a);
print sha1_hash_finish(sha1b);
local sha256a = sha256_hash_init();
sha256_hash_update(sha256a, "one");
local sha256b = copy(sha256a);
sha256_hash_update(sha256a, "two");
sha256_hash_update(sha256b, "two");
print sha256_hash_finish(sha256a);
print sha256_hash_finish(sha256b);
print "============ X509";
local x509 = x509_from_der("\x30\x82\x03\x75\x30\x82\x02\x5D\xA0\x03\x02\x01\x02\x02\x0B\x04\x00\x00\x00\x00\x01\x15\x4B\x5A\xC3\x94\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30\x57\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x45\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x47\x6C\x6F\x62\x61\x6C\x53\x69\x67\x6E\x20\x6E\x76\x2D\x73\x61\x31\x10\x30\x0E\x06\x03\x55\x04\x0B\x13\x07\x52\x6F\x6F\x74\x20\x43\x41\x31\x1B\x30\x19\x06\x03\x55\x04\x03\x13\x12\x47\x6C\x6F\x62\x61\x6C\x53\x69\x67\x6E\x20\x52\x6F\x6F\x74\x20\x43\x41\x30\x1E\x17\x0D\x39\x38\x30\x39\x30\x31\x31\x32\x30\x30\x30\x30\x5A\x17\x0D\x32\x38\x30\x31\x32\x38\x31\x32\x30\x30\x30\x30\x5A\x30\x57\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x45\x31\x19\x30\x17\x06\x03\x55\x04\x0A\x13\x10\x47\x6C\x6F\x62\x61\x6C\x53\x69\x67\x6E\x20\x6E\x76\x2D\x73\x61\x31\x10\x30\x0E\x06\x03\x55\x04\x0B\x13\x07\x52\x6F\x6F\x74\x20\x43\x41\x31\x1B\x30\x19\x06\x03\x55\x04\x03\x13\x12\x47\x6C\x6F\x62\x61\x6C\x53\x69\x67\x6E\x20\x52\x6F\x6F\x74\x20\x43\x41\x30\x82\x01\x22\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xDA\x0E\xE6\x99\x8D\xCE\xA3\xE3\x4F\x8A\x7E\xFB\xF1\x8B\x83\x25\x6B\xEA\x48\x1F\xF1\x2A\xB0\xB9\x95\x11\x04\xBD\xF0\x63\xD1\xE2\x67\x66\xCF\x1C\xDD\xCF\x1B\x48\x2B\xEE\x8D\x89\x8E\x9A\xAF\x29\x80\x65\xAB\xE9\xC7\x2D\x12\xCB\xAB\x1C\x4C\x70\x07\xA1\x3D\x0A\x30\xCD\x15\x8D\x4F\xF8\xDD\xD4\x8C\x50\x15\x1C\xEF\x50\xEE\xC4\x2E\xF7\xFC\xE9\x52\xF2\x91\x7D\xE0\x6D\xD5\x35\x30\x8E\x5E\x43\x73\xF2\x41\xE9\xD5\x6A\xE3\xB2\x89\x3A\x56\x39\x38\x6F\x06\x3C\x88\x69\x5B\x2A\x4D\xC5\xA7\x54\xB8\x6C\x89\xCC\x9B\xF9\x3C\xCA\xE5\xFD\x89\xF5\x12\x3C\x92\x78\x96\xD6\xDC\x74\x6E\x93\x44\x61\xD1\x8D\xC7\x46\xB2\x75\x0E\x86\xE8\x19\x8A\xD5\x6D\x6C\xD5\x78\x16\x95\xA2\xE9\xC8\x0A\x38\xEB\xF2\x24\x13\x4F\x73\x54\x93\x13\x85\x3A\x1B\xBC\x1E\x34\xB5\x8B\x05\x8C\xB9\x77\x8B\xB1\xDB\x1F\x20\x91\xAB\x09\x53\x6E\x90\xCE\x7B\x37\x74\xB9\x70\x47\x91\x22\x51\x63\x16\x79\xAE\xB1\xAE\x41\x26\x08\xC8\x19\x2B\xD1\x46\xAA\x48\xD6\x64\x2A\xD7\x83\x34\xFF\x2C\x2A\xC1\x6C\x19\x43\x4A\x07\x85\xE7\xD3\x7C\xF6\x21\x68\xEF\xEA\xF2\x52\x9F\x7F\x93\x90\xCF\x02\x03\x01\x00\x01\xA3\x42\x30\x40\x30\x0E\x06\x03\x55\x1D\x0F\x01\x01\xFF\x04\x04\x03\x02\x01\x06\x30\x0F\x06\x03\x55\x1D\x13\x01\x01\xFF\x04\x05\x30\x03\x01\x01\xFF\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x60\x7B\x66\x1A\x45\x0D\x97\xCA\x89\x50\x2F\x7D\x04\xCD\x34\xA8\xFF\xFC\xFD\x4B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\xD6\x73\xE7\x7C\x4F\x76\xD0\x8D\xBF\xEC\xBA\xA2\xBE\x34\xC5\x28\x32\xB5\x7C\xFC\x6C\x9C\x2C\x2B\xBD\x09\x9E\x53\xBF\x6B\x5E\xAA\x11\x48\xB6\xE5\x08\xA3\xB3\xCA\x3D\x61\x4D\xD3\x46\x09\xB3\x3E\xC3\xA0\xE3\x63\x55\x1B\xF2\xBA\xEF\xAD\x39\xE1\x43\xB9\x38\xA3\xE6\x2F\x8A\x26\x3B\xEF\xA0\x50\x56\xF9\xC6\x0A\xFD\x38\xCD\xC4\x0B\x70\x51\x94\x97\x98\x04\xDF\xC3\x5F\x94\xD5\x15\xC9\x14\x41\x9C\xC4\x5D\x75\x64\x15\x0D\xFF\x55\x30\xEC\x86\x8F\xFF\x0D\xEF\x2C\xB9\x63\x46\xF6\xAA\xFC\xDF\xBC\x69\xFD\x2E\x12\x48\x64\x9A\xE0\x95\xF0\xA6\xEF\x29\x8F\x01\xB1\x15\xB5\x0C\x1D\xA5\xFE\x69\x2C\x69\x24\x78\x1E\xB3\xA7\x1C\x71\x62\xEE\xCA\xC8\x97\xAC\x17\x5D\x8A\xC2\xF8\x47\x86\x6E\x2A\xC4\x56\x31\x95\xD0\x67\x89\x85\x2B\xF9\x6C\xA6\x5D\x46\x9D\x0C\xAA\x82\xE4\x99\x51\xDD\x70\xB7\xDB\x56\x3D\x61\xE4\x6A\xE1\x5C\xD6\xF6\xFE\x3D\xDE\x41\xCC\x07\xAE\x63\x52\xBF\x53\x53\xF4\x2B\xE9\xC7\xFD\xB6\xF7\x82\x5F\x85\xD2\x41\x18\xDB\x81\xB3\x04\x1C\xC5\x1F\xA4\x80\x6F\x15\x20\xC9\xDE\x0C\x88\x0A\x1D\xD6\x66\x55\xE2\xFC\x48\xC9\x29\x26\x69\xE0");
local x5092 = copy(x509);
print x509_parse(x509);
print x509_parse(x5092);
print "============ Entropy";
local handle = entropy_test_init();
entropy_test_add(handle, "dh3Hie02uh^s#Sdf9L3frd243h$d78r2G4cM6*Q05d(7rh46f!0|4-f");
local handle2 = copy(handle);
print entropy_test_finish(handle);
print entropy_test_finish(handle2);
}

View file

@ -1,196 +0,0 @@
# Note: opaque types in separate test
# @TEST-GROUP: leaks
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b -r $TRACES/wikipedia.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
type MyEnum: enum { ENUMME };
type InnerTestRecord: record {
a: string;
};
type TestRecord: record {
s1: string;
s2: string;
i1: InnerTestRecord;
i2: InnerTestRecord &optional;
donotset: InnerTestRecord &optional;
def: count &default=5;
};
function join_count_set(ss: set[count], j: string): string
{
local output="";
local i=0;
for ( s in ss )
{
if ( i > 0 )
output = cat(output, j);
output = cat(output, s);
++i;
}
return output;
}
function do_format(i: any): any
{
local tpe = type_name(i);
switch ( tpe )
{
case "set[count]":
return join_count_set(i, ",");
case "table[string] of string":
local cast: table[string] of string = i;
local vout: vector of string = vector();
for ( el in cast )
{
vout += cat(el, "=", cast[el]);
}
return join_string_vec(vout, ";");
}
return i;
}
function check(o1: any, o2: any, equal: bool, expect_same: bool)
{
local expect_msg = (equal ? "ok" : "FAIL0");
local same = same_object(o1, o2);
if ( expect_same && ! same )
expect_msg = "FAIL1";
if ( ! expect_same && same )
expect_msg = "FAIL2";
print fmt("orig=%s (%s) clone=%s (%s) equal=%s same_object=%s (%s)", do_format(o1), type_name(o1), do_format(o2), type_name(o2), equal, same, expect_msg);
}
function check_vector_equal(a: vector of count, b: vector of count): bool
{
if ( |a| != |b| )
return F;
for ( i in a )
{
if ( a[i] != b[i] )
return F;
}
return T;
}
function check_string_table_equal(a: table[string] of string, b: table[string] of string): bool
{
if ( |a| != |b| )
return F;
for ( i in a )
{
if ( a[i] != b[i] )
return F;
}
return T;
}
function compare_otr(a: TestRecord, b: TestRecord): bool
{
if ( a$s1 != b$s1 )
return F;
if ( a$s2 != b$s2 )
return F;
if ( a$i1$a != b$i1$a )
return F;
if ( a$i2$a != b$i2$a )
return F;
if ( same_object(a$i1, b$i1) )
return F;
if ( same_object(a$i2, b$i2) )
return F;
# check that we restroe that i1 & i2 point to same object
if ( ! same_object(a$i1, a$i2) )
return F;
if ( ! same_object(b$i1, b$i2) )
return F;
if ( a$def != b$def )
return F;
return T;
}
global did_it = F;
event new_connection(c: connection)
{
if ( did_it )
return;
did_it = T;
local i1 = -42;
local i2 = copy(i1);
check(i1, i2, i1 == i2, T);
local c1 : count = 42;
local c2 = copy(c1);
check(c1, c2, c1 == c2, T);
local a1 = 127.0.0.1;
local a2 = copy(a1);
check(a1, a2, a1 == a2, T);
local p1 = 42/tcp;
local p2 = copy(p1);
check(p1, p2, p1 == p2, T);
local sn1 = 127.0.0.1/24;
local sn2 = copy(sn1);
check(sn1, sn2, sn1 == sn2, T);
local s1 = "Foo";
local s2 = copy(s1);
check(s1, s2, s1 == s2, F);
local pat1 = /.*PATTERN.*/;
local pat2 = copy(pat1);
# patterns cannot be directoy compared
if ( same_object(pat1, pat2) )
print "FAIL P1";
if ( ! ( pat1 == "PATTERN" ) )
print "FAIL P2";
if ( ! ( pat2 == "PATTERN" ) )
print "FAIL P3";
if ( pat2 == "PATERN" )
print "FAIL P4";
print fmt("orig=%s (%s) clone=%s (%s) same_object=%s", pat1, type_name(pat1), pat2, type_name(pat2), same_object(pat1, pat2));
local set1 = [1, 2, 3, 4, 5];
local set2 = copy(set1);
check(set1, set2, set1 == set2, F);
local v1 = vector(1, 2, 3, 4, 5);
local v2 = copy(v1);
check(v1, v2, check_vector_equal(v1, v2), F);
local t1 : table[string] of string = table();
t1["a"] = "va";
t1["b"] = "vb";
local t2 = copy(t1);
check(t1, t2, check_string_table_equal(t1, t2), F);
local e1 = ENUMME;
local e2 = copy(ENUMME);
check(e1, e2, e1 == e2, T);
local itr = InnerTestRecord($a="a");
local otr1 = TestRecord($s1="s1", $s2="s2", $i1=itr, $i2=itr);
local otr2 = copy(otr1);
check(otr1, otr2, compare_otr(otr1, otr2), F);
}

View file

@ -1,40 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -b -C -m -r $TRACES/dnssec/nsec3.pcap %INPUT
# @TEST-EXEC: btest-bg-wait 90
@load policy/protocols/dns/auth-addl
event dns_RRSIG(c: connection, msg: dns_msg, ans: dns_answer, rrsig: dns_rrsig_rr)
{
print "RRSIG", rrsig, bytestring_to_hexstr(rrsig$signature);
}
event dns_DNSKEY(c: connection, msg: dns_msg, ans: dns_answer, dnskey: dns_dnskey_rr)
{
print "DNSKEY", dnskey, bytestring_to_hexstr(dnskey$public_key);
}
event dns_NSEC(c: connection, msg: dns_msg, ans: dns_answer, next_name: string, bitmaps: string_vec)
{
print "NSEC", next_name, bitmaps;
for ( i in bitmaps )
print bytestring_to_hexstr(bitmaps[i]);
}
event dns_NSEC3(c: connection, msg: dns_msg, ans: dns_answer, nsec3: dns_nsec3_rr)
{
print "NSEC3", nsec3,
bytestring_to_hexstr(nsec3$nsec_salt),
bytestring_to_hexstr(nsec3$nsec_hash);
}
event dns_DS(c: connection, msg: dns_msg, ans: dns_answer, ds: dns_ds_rr)
{
print "DS", ds, bytestring_to_hexstr(ds$digest_val);
}

View file

@ -1,42 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -b -m -r $TRACES/wikipedia.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
redef exit_only_after_terminate = T;
global n1 = 0;
function check_term_conditions()
{
if ( n1 > 7 )
terminate();
}
event do_txt(s: string)
{
when ( local t1 = lookup_hostname_txt(s) )
{
print "t1", t1;
++n1;
check_term_conditions();
}
timeout 100secs
{
print "t1 timeout";
++n1;
check_term_conditions();
}
}
event connection_established(c: connection)
{
event do_txt("localhost");
schedule 5sec { do_txt("localhost") };
}

View file

@ -1,81 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -b -m -r $TRACES/wikipedia.trace %INPUT
# @TEST-EXEC: btest-bg-wait 90
redef exit_only_after_terminate = T;
const foo: set[addr] = {
google.com
};
global n1 = 0;
global n2 = 0;
global n3 = 0;
global n4 = 0;
function check_term_conditions()
{
if ( n1 > 4 && n2 > 4 && n3 > 4 && n4 > 4 )
terminate();
}
event connection_established(c: connection)
{
when ( local addrs = lookup_hostname("localhost") )
{
print "1a", c$id$resp_h, addrs;
++n1;
check_term_conditions();
}
timeout 100secs
{
print "1b", c$id$resp_h;
++n1;
check_term_conditions();
}
when ( local addrs2 = lookup_hostname("qq.ww.ee.rrrrr") )
{
print "2a", c$id$resp_h, addrs2;
++n2;
check_term_conditions();
}
timeout 100secs
{
print "2b", c$id$resp_h;
++n2;
check_term_conditions();
}
when ( local a = lookup_addr(c$id$resp_h) )
{
print "3a", c$id$resp_h, a;
++n3;
check_term_conditions();
}
timeout 100secs
{
print "3b", c$id$resp_h;
++n3;
check_term_conditions();
}
when ( local a2 = lookup_addr(1.2.3.4) )
{
print "4a", c$id$resp_h, a2;
++n4;
check_term_conditions();
}
timeout 100secs
{
print "4b", c$id$resp_h;
++n4;
check_term_conditions();
}
}

View file

@ -1,15 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -b -m -r $TRACES/tls/dtls1_0.pcap %INPUT
# @TEST-EXEC: btest-bg-wait 90
@load base/protocols/ssl
event ssl_established(c: connection) &priority=3
{
print "established";
}

View file

@ -1,79 +0,0 @@
# Needs perftools support.
#
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: zeek --help 2>&1 | grep -q mem-leaks
#
# @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run zeek zeek -m -b ../exectest.zeek
# @TEST-EXEC: btest-bg-wait 90
@TEST-START-FILE exectest.zeek
@load base/utils/exec
redef exit_only_after_terminate = T;
global c: count = 0;
function check_exit_condition()
{
c += 1;
if ( c == 3 )
terminate();
}
function test_cmd(label: string, cmd: Exec::Command)
{
when ( local result = Exec::run(cmd) )
{
print label, result;
check_exit_condition();
}
}
event zeek_init()
{
test_cmd("test1", [$cmd="bash ../somescript.sh",
$read_files=set("out1", "out2")]);
test_cmd("test2", [$cmd="bash ../nofiles.sh"]);
# Not sure of a portable way to test signals yet.
#test_cmd("test3", [$cmd="bash ../suicide.sh"]);
test_cmd("test4", [$cmd="bash ../stdin.sh", $stdin="hibye"]);
}
@TEST-END-FILE
@TEST-START-FILE somescript.sh
#! /usr/bin/env bash
echo "insert text here" > out1
echo "and here" >> out1
echo "insert more text here" > out2
echo "and there" >> out2
echo "done"
echo "exit"
echo "stop"
@TEST-END-FILE
@TEST-START-FILE nofiles.sh
#! /usr/bin/env bash
echo "here's something on stdout"
echo "some more stdout"
echo "last stdout"
echo "and some stderr" 1>&2
echo "more stderr" 1>&2
echo "last stderr" 1>&2
exit 1
@TEST-END-FILE
@TEST-START-FILE suicide.sh
#! /usr/bin/env bash
echo "FML"
kill -9 $$
echo "nope"
@TEST-END-FILE
@TEST-START-FILE stdin.sh
#! /usr/bin/env bash
read -r line
echo "$line"
@TEST-END-FILE

Some files were not shown because too many files have changed in this diff Show more