Skip to content

Run the test suite under ASan and UBSan in CI - #51

Merged
zirui-song-18 merged 1 commit into
opensearch-project:mainfrom
chishui:sanitizer-ci
Sep 9, 2026
Merged

Run the test suite under ASan and UBSan in CI#51
zirui-song-18 merged 1 commit into
opensearch-project:mainfrom
chishui:sanitizer-ci

Conversation

@chishui

@chishui chishui commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Resolves part 1 of #50. Adds NSPARSE_ENABLE_SANITIZERS (default OFF) and one per-PR job building RelWithDebInfo with -fsanitize=address,undefined. All 639 tests pass as-is — nothing suppressed.

Answering the open questions:

  • Option? Yes; flags go on globally before any target, since mixing instrumented and uninstrumented TUs yields container-overflow false positives. -DNSPARSE_SANITIZERS=<list> overrides the default set.
  • A SIMD build too? Not needed. tests/CMakeLists.txt registers the per-ISA distance_kernel_equivalence_test binaries at every NSPARSE_OPT_LEVEL, so the generic job already runs the vectorized kernels under ASan.
  • Per-PR or nightly? Per-PR: 6m52s, inside the existing envelope (Windows is 7m39s).

-fno-sanitize-recover=all, or UBSan prints and still exits 0. UBSan's null/nonnull checks are dropped under GCC — they break abseil's constexpr hash dispatch; ASan still reports null derefs.

Verified live, not a no-op: injected OOB/UAF/overflow each aborted with a report. Fork CI green.

I confirm my contribution is made under the terms of the Apache 2.0 license.

nsparse deserializes binary index files that may be truncated or corrupt.
The readers validate defensively and ~120 negative-path assertions cover
that, but those assertions only prove an exception was thrown -- not that
no out-of-bounds read, overflow or misaligned access happened first. For
an in-process native library a memory error is much worse than an
exception, and CI built Release with no sanitizers, so nothing checked.

Add NSPARSE_ENABLE_SANITIZERS, which applies -fsanitize=address,undefined
globally before any target exists. Global is required, not tidiness: an
instrumented translation unit and an uninstrumented one disagree about
libstdc++'s container annotations, which surfaces as container-overflow
false positives rather than a link error. -fno-sanitize-recover=all goes
with it, because UBSan otherwise prints and continues and the run still
exits 0.

UBSan carries as much weight as ASan here -- overflow and misalignment are
what binary parsing produces -- but under GCC its null and nonnull-attribute
checks make the address of a function template instantiation non-constant,
which breaks abseil's constexpr hash-function dispatch in every translation
unit that includes flat_hash_map. Those three are dropped on GCC; a null
dereference still surfaces, as an ASan SEGV report.

One per-PR job, at the generic optimization level. tests/CMakeLists.txt
registers the per-ISA distance_kernel_equivalence_test binaries (and builds
nsparse_avx2/nsparse_avx512 to link them) regardless of NSPARSE_OPT_LEVEL,
so that single configuration already runs the vectorized kernels -- where
tail-element OOB would live -- under ASan; a SIMD-configured job would only
re-cover them. It runs on ubuntu-latest rather than the CI image the other
Linux jobs use, because it needs the libasan/libubsan runtimes.

All 639 tests pass as-is: no existing finding is being suppressed. Verified
the instrumentation is live, not a silent no-op, with throwaway tests -- a
heap-buffer overflow, a use-after-free and a signed overflow each aborted
the run with a report.

Default builds are unaffected: cmake/sanitizers.cmake returns before adding
any flag when the option is OFF, which it is by default. No perf claim.

A libFuzzer harness over the CSR/mmap readers is the natural follow-up.

Signed-off-by: Liyun Xiu <xiliyun@amazon.com>

@zirui-song-18 zirui-song-18 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zirui-song-18
zirui-song-18 merged commit 7ac9c3e into opensearch-project:main Sep 9, 2026
11 checks passed
@chishui
chishui deleted the sanitizer-ci branch September 9, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants