From c445bb703c5f30e03439312a315179e546abeb90 Mon Sep 17 00:00:00 2001 From: PJK Date: Sun, 22 Mar 2026 20:38:18 +0100 Subject: [PATCH 1/5] Enable LeakSanitizer (LSan) via -DSANITIZE=ON on Linux; add sanitized CI jobs - Add -fsanitize=leak to the Debug sanitizer flags, guarded by NOT APPLE (Apple's LLVM drops standalone LSan; on Linux it is included with ASan) - Add build-and-test-sanitized CircleCI job (Clang, Linux) that runs with SANITIZE=ON on every PR, replacing Valgrind as the leak-detection path - Enable SANITIZE=ON in the macOS CI job for ASan/UBSan coverage Fixes #365 Co-Authored-By: Claude Sonnet 4.6 --- .circleci/config.yml | 31 ++++++++++++++++++++++++++++++- CHANGELOG.md | 3 +++ CMakeLists.txt | 6 ++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 211db3ca..43c79ef5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,6 +35,15 @@ commands: -DCOVERAGE="${CMAKE_COVERAGE:='OFF'}" \ . - run: make -j 16 VERBOSE=1 + build-sanitized: + steps: + - run: > + cmake -DWITH_TESTS=ON \ + -DWITH_EXAMPLES=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSANITIZE=ON \ + . + - run: make -j 16 VERBOSE=1 build-release: steps: - run: > @@ -114,6 +123,19 @@ jobs: - build - test + build-and-test-sanitized: + machine: + <<: *default-machine + environment: + TOOLCHAIN_PACKAGES: clang + CC: clang + CXX: clang++ + steps: + - checkout + - linux-setup + - build-sanitized + - test + build-and-test-32b: machine: <<: *default-machine @@ -204,7 +226,13 @@ jobs: - checkout - run: bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - run: brew install cmocka cmake - - build + - run: > + cmake -DWITH_TESTS=ON \ + -DWITH_EXAMPLES=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSANITIZE=ON \ + . + - run: make -j 8 VERBOSE=1 - test @@ -289,6 +317,7 @@ workflows: - static-test - build-and-test - build-and-test-clang + - build-and-test-sanitized - build-and-test-32b - build-and-test-release-clang - build-and-test-arm diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca8bd1c..d941d558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ Next - Signature: `cbor_map_get(map, key, eq)` — pass any equality predicate, e.g. `cbor_structurally_equal` - Parameterised equality allows type-specific comparators or custom data-model semantics without library changes - See also: #96 +- [Enable LeakSanitizer (LSan) as part of `-DSANITIZE=ON` on Linux; enable sanitizers in macOS CI](https://github.com/PJK/libcbor/pull/XXX) + - LSan is automatically included via ASan on Linux; Apple's LLVM does not support LSan so it is excluded on macOS + - A new `build-and-test-sanitized` CircleCI job runs Clang with all sanitizers enabled on every PR - [Add `cbor_structurally_equal` for encoding-level item comparison](https://github.com/PJK/libcbor/pull/408) - Compares two items structurally: encoding width, definite-vs-indefinite length, chunk boundaries, and map entry order all count - Runs in O(n) time in the encoded byte size with no additional allocations diff --git a/CMakeLists.txt b/CMakeLists.txt index 024954c7..cdd712ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,12 @@ else() "${CMAKE_C_FLAGS_DEBUG} \ -fsanitize=undefined -fsanitize=address \ -fsanitize=bounds -fsanitize=alignment") + # LSan is not supported on Apple platforms (it's integrated into ASan on + # Linux but Apple's LLVM drops standalone LSan support entirely) + if(NOT APPLE) + set(CMAKE_C_FLAGS_DEBUG + "${CMAKE_C_FLAGS_DEBUG} -fsanitize=leak") + endif() endif() set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g") From 6f0dad6a7fda9acf9a7b3c51d14a4f53507bfec7 Mon Sep 17 00:00:00 2001 From: PJK Date: Sun, 22 Mar 2026 20:39:00 +0100 Subject: [PATCH 2/5] Remove changelog entry (internal CI/build change, no user impact) --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d941d558..9ca8bd1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,9 +23,6 @@ Next - Signature: `cbor_map_get(map, key, eq)` — pass any equality predicate, e.g. `cbor_structurally_equal` - Parameterised equality allows type-specific comparators or custom data-model semantics without library changes - See also: #96 -- [Enable LeakSanitizer (LSan) as part of `-DSANITIZE=ON` on Linux; enable sanitizers in macOS CI](https://github.com/PJK/libcbor/pull/XXX) - - LSan is automatically included via ASan on Linux; Apple's LLVM does not support LSan so it is excluded on macOS - - A new `build-and-test-sanitized` CircleCI job runs Clang with all sanitizers enabled on every PR - [Add `cbor_structurally_equal` for encoding-level item comparison](https://github.com/PJK/libcbor/pull/408) - Compares two items structurally: encoding width, definite-vs-indefinite length, chunk boundaries, and map entry order all count - Runs in O(n) time in the encoded byte size with no additional allocations From e89361b1402236aedb01e0034d3dbb6a0b2e52d5 Mon Sep 17 00:00:00 2001 From: PJK Date: Sun, 22 Mar 2026 20:43:55 +0100 Subject: [PATCH 3/5] Use build-sanitized command in macOS CI job --- .circleci/config.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 43c79ef5..efae0919 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -226,13 +226,7 @@ jobs: - checkout - run: bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - run: brew install cmocka cmake - - run: > - cmake -DWITH_TESTS=ON \ - -DWITH_EXAMPLES=ON \ - -DCMAKE_BUILD_TYPE=Debug \ - -DSANITIZE=ON \ - . - - run: make -j 8 VERBOSE=1 + - build-sanitized - test From f94431084d0f804758fa32b52c06505fd3b89053 Mon Sep 17 00:00:00 2001 From: PJK Date: Sun, 22 Mar 2026 21:00:04 +0100 Subject: [PATCH 4/5] Remove explicit -fsanitize=leak: LSan is bundled in ASan on Linux Adding -fsanitize=leak alongside -fsanitize=address links two LSan runtimes which conflict at startup and cause crashes. ASan on Linux x86_64/aarch64 already enables LSan by default (detect_leaks=1). https://clang.llvm.org/docs/LeakSanitizer.html --- CMakeLists.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cdd712ed..5ef16fa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,12 +103,11 @@ else() "${CMAKE_C_FLAGS_DEBUG} \ -fsanitize=undefined -fsanitize=address \ -fsanitize=bounds -fsanitize=alignment") - # LSan is not supported on Apple platforms (it's integrated into ASan on - # Linux but Apple's LLVM drops standalone LSan support entirely) - if(NOT APPLE) - set(CMAKE_C_FLAGS_DEBUG - "${CMAKE_C_FLAGS_DEBUG} -fsanitize=leak") - endif() + # Note: LeakSanitizer (LSan) is automatically enabled by ASan on Linux + # x86_64/aarch64 (detect_leaks=1 by default). Adding -fsanitize=leak + # explicitly would link a second LSan runtime alongside ASan's bundled one + # and cause crashes. Apple's LLVM does not support LSan at all. + # https://clang.llvm.org/docs/LeakSanitizer.html endif() set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g") From 9fddf34524370251a253ff71472ebdb06deb57a5 Mon Sep 17 00:00:00 2001 From: PJK Date: Sun, 22 Mar 2026 21:05:14 +0100 Subject: [PATCH 5/5] Disable ASLR before sanitized tests to fix ASan shadow memory crashes Ubuntu 22.04 raised mmap_rnd_bits to 28, which conflicts with ASan's fixed shadow memory offsets and causes random startup crashes across different test binaries between runs. https://github.com/google/sanitizers/issues/1716 --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index efae0919..a7cb6404 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -134,6 +134,10 @@ jobs: - checkout - linux-setup - build-sanitized + # Ubuntu 22.04 raises mmap_rnd_bits to 28, which conflicts with ASan's + # fixed shadow memory offsets and causes random startup crashes. + # https://github.com/google/sanitizers/issues/1716 + - run: sudo sysctl -w kernel.randomize_va_space=0 - test build-and-test-32b: