diff --git a/.circleci/config.yml b/.circleci/config.yml index 77dc8cdb3..f951f9de3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,13 +29,26 @@ jobs: CXX: clang++-8 CLANG_FORMAT: clang-format-8 CLANG_TIDY: clang-tidy-8 + NO_NIST_STS: 1 WITH_FATAL_WARNINGS: yes + WITH_FATAL_SANITIZERS: yes steps: - run: sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install default-jdk nodejs npm - checkout - run: git reset HEAD && git submodule sync && git submodule update --init - run: make fmt_check ENGINE=boringssl - run: make fmt_check ENGINE=openssl + - run: make clean && make test CC=gcc-8 WITH_ASAN=1 + - run: make clean && make test CC=gcc-8 WITH_TSAN=1 + # Currently the code has quite a few UBSAN violations and GCC does not provide a convenient + # way to silence individual warnings. Disable UBSAN runs for GCC for now. +# - run: make clean && make test CC=gcc-8 WITH_UBSAN=1 + - run: make clean && make test CC=clang-8 WITH_ASAN=1 + # MSAN is currently supported only by Clang. However, it produces a lot of false positives + # due to OpenSSL not being instrumented and intentionally using uninitialized memory. +# - run: make clean && make test CC=clang-8 WITH_MSAN=1 + - run: make clean && make test CC=clang-8 WITH_TSAN=1 + - run: make clean && make test CC=clang-8 WITH_UBSAN=1 x86_64: docker: diff --git a/Makefile b/Makefile index cc0b10b33..827354af9 100644 --- a/Makefile +++ b/Makefile @@ -229,12 +229,22 @@ endif # our compilation flags there, so do not export these variables. unexport CFLAGS LDFLAGS +# Prevent undefined symbols in produced binaries, but allow them for sanitizers +# which expect the libraries linked into the main executable to be underlinked. +ifndef WITH_ASAN +ifndef WITH_MSAN +ifndef WITH_TSAN +ifndef WITH_UBSAN ifdef IS_MACOS LDFLAGS += -Wl,-undefined,error endif ifdef IS_LINUX LDFLAGS += -Wl,--no-undefined endif +endif +endif +endif +endif CFLAGS += -O2 -fno-omit-frame-pointer -g @@ -299,6 +309,64 @@ endif CFLAGS += -fvisibility=hidden +# +# Enable code sanitizers on demand and if supported by compiler +# + +ifdef WITH_ASAN +ifeq (yes,$(call supported,-fsanitize=address)) +SANITIZERS += -fsanitize=address +else +$(error -fsanitize=address requested but $(CC) does not seem to support it) +endif +endif + +ifdef WITH_MSAN +ifeq (yes,$(call supported,-fsanitize=memory)) +SANITIZERS += -fsanitize=memory -fsanitize-memory-track-origins=2 +else +$(error -fsanitize=memory requested but $(CC) does not seem to support it) +endif +endif + +ifdef WITH_TSAN +ifeq (yes,$(call supported,-fsanitize=thread)) +SANITIZERS += -fsanitize=thread +else +$(error -fsanitize=thread requested but $(CC) does not seem to support it) +endif +endif + +ifdef WITH_UBSAN +ifeq (yes,$(call supported,-fsanitize=undefined)) +SANITIZERS += -fsanitize=undefined +else +$(error -fsanitize=undefined requested but $(CC) does not seem to support it) +endif +ifeq (yes,$(call supported,-fsanitize=integer)) +SANITIZERS += -fsanitize=integer +else +$(warning -fsanitize=integer not supported by $(CC), skipping...) +endif +ifeq (yes,$(call supported,-fsanitize=nullability)) +SANITIZERS += -fsanitize=nullability +else +$(warning -fsanitize=nullability not supported by $(CC), skipping...) +endif +ifeq (yes,$(call supported,-fsanitize-blacklist=src/soter/blacklist-ubsan.txt)) +SANITIZERS += -fsanitize-blacklist=src/soter/blacklist-ubsan.txt +else +$(warning -fsanitize-blacklist not supported by $(CC), skipping...) +endif +endif + +ifeq (yes,$(WITH_FATAL_SANITIZERS)) +SANITIZERS += -fno-sanitize-recover=all +endif + +CFLAGS += $(SANITIZERS) +LDFLAGS += $(SANITIZERS) + # Binary format compatibility with Themis 0.9.6 on x86_64 architecture. # https://github.com/cossacklabs/themis/pull/279 ifeq ($(NO_SCELL_COMPAT),) diff --git a/src/soter/blacklist-ubsan.txt b/src/soter/blacklist-ubsan.txt new file mode 100644 index 000000000..ddf6d999f --- /dev/null +++ b/src/soter/blacklist-ubsan.txt @@ -0,0 +1,26 @@ +# Disable ubsan warnings about integer handling in third-party ed25519 library +[integer] +src:src/soter/ed25519/* + +# FIXME: avoid misaligned memory accesses instead of silencing warnings here +# Disable warnings for `soter_container_hdr_t*` casts +[alignment] +src:src/soter/boringssl/soter_asym_cipher.c +src:src/soter/boringssl/soter_asym_ka.c +src:src/soter/boringssl/soter_ec_key.c +src:src/soter/boringssl/soter_ecdsa_common.c +src:src/soter/boringssl/soter_rsa_common.c +src:src/soter/boringssl/soter_rsa_key.c +src:src/soter/openssl/soter_asym_cipher.c +src:src/soter/openssl/soter_asym_ka.c +src:src/soter/openssl/soter_ec_key.c +src:src/soter/openssl/soter_ecdsa_common.c +src:src/soter/openssl/soter_rsa_common.c +src:src/soter/openssl/soter_rsa_key.c +src:src/soter/soter_container.c +src:src/themis/secure_keygen.c +src:src/themis/secure_message_wrapper.c +src:src/themis/secure_session.c +src:src/themis/secure_session_message.c +src:src/themis/secure_session_serialize.c +src:src/themis/secure_session_utils.c diff --git a/src/soter/soter_container.h b/src/soter/soter_container.h index 594f38ad4..a291829ee 100644 --- a/src/soter/soter_container.h +++ b/src/soter/soter_container.h @@ -24,8 +24,8 @@ struct soter_container_hdr_type { char tag[SOTER_CONTAINER_TAG_LENGTH]; - int32_t size; /* Size is data + sizeof(soter_container_hdr_t), so should be not less than - sizeof(soter_container_hdr_t). Network byte order. */ + uint32_t size; /* Size is data + sizeof(soter_container_hdr_t), so should be not less than + sizeof(soter_container_hdr_t). Network byte order. */ uint32_t crc; }; diff --git a/src/soter/soter_crc32.c b/src/soter/soter_crc32.c index e40607607..e14d09235 100644 --- a/src/soter/soter_crc32.c +++ b/src/soter/soter_crc32.c @@ -63,7 +63,7 @@ static uint32_t crc_c[256] = { soter_crc32_t soter_crc32_create(void) { - return ~0L; + return 0xFFFFFFFF; } void soter_crc32_update(soter_crc32_t* crc, const void* buf, size_t len)