diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 2fa35c8d3c..6ff7c98359 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -1120,6 +1120,38 @@ jobs: - run: suricata-update -V - run: suricatasc -h + # Build both C and Rust with AddressSanitizer, then run Suricata-Verify. + fedora-44-rust-asan: + name: Fedora 44 (rust-asan, sv) + runs-on: ubuntu-latest + container: fedora:44 + needs: [prepare-deps] + steps: + - name: Cache cargo registry + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 + with: + path: ~/.cargo/registry + key: ${{ github.job }}-cargo-registry + - run: dnf -y install git + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + with: + name: prep + path: prep + - run: tar xf prep/suricata-update.tar.gz + - run: tar xf prep/suricata-verify.tar.gz + - name: Build and test with Rust ASAN + run: ./qa/ci/rust-asan.sh + - name: Upload failure logs + if: failure() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: rust-asan-logs + if-no-files-found: ignore + path: | + *.log + suricata-verify/tests/**/output/ + # This job builds and tests Suricata as a non-root user as some # issues only show up when not running as root, and by default all # jobs in GitHub actions are run as root inside the container. diff --git a/qa/ci/rust-asan.sh b/qa/ci/rust-asan.sh new file mode 100755 index 0000000000..1954c4434f --- /dev/null +++ b/qa/ci/rust-asan.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# +# Build with Rust and C ASAN. + +set -eux +set -o pipefail + +# This script and its package list currently only target Fedora. +if [ ! -e /etc/fedora-release ]; then + echo "ERROR: this script is only supported on Fedora" >&2 + exit 1 +fi + +# Pin to a specific nightly, should be updated from time to time. +NIGHTLY="2026-09-18" + +# A cargo build target other than the default is required for Rust ASAN builds +# as we don't want proc-macros built with address sanitization. +export CARGO_BUILD_TARGET="${CARGO_BUILD_TARGET:=x86_64-unknown-linux-gnu}" + +# Default to all CPUs unless already set. +: "${CPUS:=$(nproc --all)}" + +CFLAGS=( + -Wall + -Wextra + -Werror + -Wno-unused-parameter + -Wno-unused-function + -g + -fno-omit-frame-pointer + -fsanitize=address +) + +LDFLAGS=( + -fsanitize=address +) + +RUSTFLAGS=( + -Zsanitizer=address + -Cforce-frame-pointers=yes +) + +export ac_cv_func_realloc_0_nonnull=yes +export ac_cv_func_malloc_0_nonnull=yes + +dnf -y install \ + autoconf \ + automake \ + awk \ + cbindgen \ + curl \ + diffutils \ + file-devel \ + gcc \ + gcc-c++ \ + git \ + jq \ + jansson-devel \ + libasan \ + libtool \ + libyaml-devel \ + libnfnetlink-devel \ + libnetfilter_queue-devel \ + libnet-devel \ + libcap-ng-devel \ + libpcap-devel \ + make \ + pcre2-devel \ + pkgconfig \ + python3-yaml \ + which \ + xz-devel \ + zlib-devel + +# Nightly is required for -Zsanitizer=address. +curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-${NIGHTLY} --profile minimal -y +. "${HOME}/.cargo/env" + +./autogen.sh + +CFLAGS="${CFLAGS[@]}" LDFLAGS="${LDFLAGS[@]}" \ + ./configure --enable-warnings --enable-debug --enable-unittests --disable-shared + +RUSTFLAGS="${RUSTFLAGS[@]}" make -j "${CPUS}" + +# Check that the Rust is built with ASAN. +lib="rust/target/${CARGO_BUILD_TARGET}/debug/libsuricata_rust.a" +nm -C "${lib}" > rust-asan-symbols.txt +grep -q __asan_report_load1 rust-asan-symbols.txt + +./src/suricata --build-info +./src/suricata -u -l . + +# Only disable leak detection here, there are leaks in the Rust unit tests, to +# be investigated. +(cd rust && \ + ASAN_OPTIONS="detect_leaks=0" RUSTFLAGS="${RUSTFLAGS[@]}" \ + cargo test --workspace --all-targets) + +SURICATASC=./rust/target/${CARGO_BUILD_TARGET}/debug/suricatasc \ + python3 ./suricata-verify/run.py -q --debug-failed