Add framework for running UndefinedBehaviorSanitizer in CI

Many checks are initially disabled because they do cause failures
when running the test suites.
This commit is contained in:
Jon Siwek 2020-09-16 16:14:15 -07:00
parent eca8540147
commit efcbf979f5
5 changed files with 72 additions and 4 deletions

View file

@ -4,7 +4,7 @@ btest_retries: &BTEST_RETRIES 2
memory: &MEMORY 4GB
config: &CONFIG --build-type=release --enable-cpp-tests --disable-broker-tests --prefix=$CIRRUS_WORKING_DIR/install
memcheck_config: &MEMCHECK_CONFIG --build-type=debug --enable-cpp-tests --disable-broker-tests --sanitizers=address --enable-fuzzers
sanitizer_config: &SANITIZER_CONFIG --build-type=debug --enable-cpp-tests --disable-broker-tests --sanitizers=address,undefined --enable-fuzzers
resources_template: &RESOURCES_TEMPLATE
cpu: *CPUS
@ -151,7 +151,7 @@ freebsd_task:
prepare_script: ./ci/freebsd/prepare.sh
<< : *CI_TEMPLATE
memcheck_task:
sanitizer_task:
container:
# Just uses a recent/common distro to run memory error/leak checks.
dockerfile: ci/ubuntu-18.04/Dockerfile
@ -161,4 +161,6 @@ memcheck_task:
<< : *CI_TEMPLATE
test_fuzzers_script: ./ci/test-fuzzers.sh
env:
ZEEK_CI_CONFIGURE_FLAGS: *MEMCHECK_CONFIG
ZEEK_CI_CONFIGURE_FLAGS: *SANITIZER_CONFIG
ZEEK_TAILORED_UB_CHECKS: 1
UBSAN_OPTIONS: print_stacktrace=1

View file

@ -134,7 +134,71 @@ if ( ZEEK_SANITIZERS )
# interfere with the detection and cause CMAKE_THREAD_LIBS_INIT to not
# include -lpthread when it should.
find_package(Threads)
string(REPLACE "," " " _sanitizer_args "${ZEEK_SANITIZERS}")
separate_arguments(_sanitizer_args)
set(ZEEK_SANITIZERS "")
foreach ( _sanitizer ${_sanitizer_args} )
if ( ZEEK_SANITIZERS )
set(ZEEK_SANITIZERS "${ZEEK_SANITIZERS},")
endif ()
if ( NOT _sanitizer STREQUAL "undefined" )
set(ZEEK_SANITIZERS "${ZEEK_SANITIZERS}${_sanitizer}")
continue()
endif ()
if ( NOT DEFINED ZEEK_SANITIZER_UB_CHECKS )
if ( DEFINED ENV{ZEEK_TAILORED_UB_CHECKS} )
# list(APPEND _check_list "alignment") # TODO: fix associated errors
list(APPEND _check_list "bool")
# list(APPEND _check_list "builtin") # Not implemented in older GCCs
list(APPEND _check_list "bounds") # Covers both array/local bounds options below
# list(APPEND _check_list "array-bounds") # Not implemented by GCC
# list(APPEND _check_list "local-bounds") # Not normally part of "undefined"
list(APPEND _check_list "enum")
list(APPEND _check_list "float-cast-overflow")
list(APPEND _check_list "float-divide-by-zero")
# list(APPEND _check_list "function") # Not implemented by GCC
# list(APPEND _check_list "implicit-unsigned-integer-truncation") # Not truly UB
# list(APPEND _check_list "implicit-signed-integer-truncation") # Not truly UB
# list(APPEND _check_list "implicit-integer-sign-change") # Not truly UB
list(APPEND _check_list "integer-divide-by-zero")
list(APPEND _check_list "nonnull-attribute")
# list(APPEND _check_list "null") # TODO: fix associated errors
# list(APPEND _check_list "nullability-arg") # Not normally part of "undefined"
# list(APPEND _check_list "nullability-assign") # Not normally part of "undefined"
# list(APPEND _check_list "nullability-return") # Not normally part of "undefined"
# list(APPEND _check_list "objc-cast") # Not truly UB
list(APPEND _check_list "object-size")
# list(APPEND _check_list "pointer-overflow") # Not implemented in older GCCs
list(APPEND _check_list "return")
list(APPEND _check_list "returns-nonnull-attribute")
list(APPEND _check_list "shift")
# list(APPEND _check_list "unsigned-shift-base") # Not implemented by GCC
list(APPEND _check_list "signed-integer-overflow")
list(APPEND _check_list "unreachable")
# list(APPEND _check_list "unsigned-integer-overflow") # Not truly UB
list(APPEND _check_list "vla-bound")
# list(APPEND _check_list "vptr") # TODO: fix associated errors
string(REPLACE ";" "," _ub_checks "${_check_list}")
set(ZEEK_SANITIZER_UB_CHECKS "${_ub_checks}" CACHE INTERNAL "" FORCE)
else ()
set(ZEEK_SANITIZER_UB_CHECKS "undefined" CACHE INTERNAL "" FORCE)
endif ()
endif ()
set(ZEEK_SANITIZERS "${ZEEK_SANITIZERS}${ZEEK_SANITIZER_UB_CHECKS}")
endforeach ()
set(_sanitizer_flags "-fsanitize=${ZEEK_SANITIZERS}")
if ( ZEEK_SANITIZER_UB_CHECKS )
set(_sanitizer_flags "${_sanitizer_flags} -fno-sanitize-recover=${ZEEK_SANITIZER_UB_CHECKS}")
endif ()
set(_sanitizer_flags "${_sanitizer_flags} -fno-omit-frame-pointer")
set(_sanitizer_flags "${_sanitizer_flags} -fno-optimize-sibling-calls")

@ -1 +1 @@
Subproject commit 14478a32981c9df98b515a223eb6e41804649bb1
Subproject commit b5bfda68dd576162c549994e280be347944426b9

View file

@ -30,3 +30,4 @@ ZEEK_DEFAULT_CONNECT_RETRY=1
ZEEK_DISABLE_ZEEKYGEN=1
ZEEK_ALLOW_INIT_ERRORS=1
ZEEK_SUPERVISOR_NO_SIGKILL=1
UBSAN_OPTIONS=print_stacktrace=1

View file

@ -22,3 +22,4 @@ ZEEK_PROFILER_FILE=%(testbase)s/.tmp/script-coverage/XXXXXX
ZEEK_DNS_FAKE=1
# For fedora 21 - they disable MD5 for certificate verification and need setting an environment variable to permit it.
OPENSSL_ENABLE_MD5_VERIFY=1
UBSAN_OPTIONS=print_stacktrace=1