Skip to content

feat: integrate hardening and static analysis features - #920

Open
niteshpurohit wants to merge 3 commits into
feat/fuzz-harnessfrom
feat/static-analysis-hardening
Open

niteshpurohit wants to merge 3 commits into
feat/fuzz-harnessfrom
feat/static-analysis-hardening

Conversation

@niteshpurohit

@niteshpurohit niteshpurohit commented Sep 12, 2026

Copy link
Copy Markdown
Member
  • Added LaghuHardening.cmake to configure hardening features such as PIE, stack protection, and fortification.
  • Introduced ExpectHardeningFailure.cmake, ExpectHardeningMetadata.cmake, and ExpectHardeningUnsupported.cmake for testing hardening configurations.
  • Implemented static analysis configuration in LaghuStaticAnalysis.cmake, allowing integration with clang-tidy, cppcheck, and clang-analyzer.
  • Created ExpectStaticAnalysisFailure.cmake and ExpectStaticAnalysisOwnership.cmake for validating static analysis outcomes.
  • Added tests for static analysis failures and ownership checks to ensure proper functionality.
  • Updated CMakeLists.txt to include new hardening and static analysis configurations and tests.
  • Refactored build identity to include hardening metadata in the output.

closes: #75
closes: #72

- Added LaghuHardening.cmake to configure hardening features such as PIE, stack protection, and fortification.
- Introduced ExpectHardeningFailure.cmake, ExpectHardeningMetadata.cmake, and ExpectHardeningUnsupported.cmake for testing hardening configurations.
- Implemented static analysis configuration in LaghuStaticAnalysis.cmake, allowing integration with clang-tidy, cppcheck, and clang-analyzer.
- Created ExpectStaticAnalysisFailure.cmake and ExpectStaticAnalysisOwnership.cmake for validating static analysis outcomes.
- Added tests for static analysis failures and ownership checks to ensure proper functionality.
- Updated CMakeLists.txt to include new hardening and static analysis configurations and tests.
- Refactored build identity to include hardening metadata in the output.

closes: #75
@niteshpurohit niteshpurohit self-assigned this Sep 12, 2026
@niteshpurohit
niteshpurohit added this pull request to stack #915 September 12, 2026 15:21
Copilot AI lite review requested due to automatic review settings September 12, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved critical and moderate issues affect build correctness, hardening validation, and static-analysis coverage.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds CMake-based hardening and static-analysis integration, including metadata, validation fixtures, and CI coverage.

Changes:

  • Adds PIE, stack protection, RELRO, binding, and fortification configuration.
  • Integrates clang-tidy, Cppcheck, and clang-analyzer.
  • Adds validation fixtures, build identity updates, and CI coverage.
File summaries
File Review summary
tests/static-analysis/ownership/third_party/src/unowned.hpp Reviewed third-party ownership fixture.
tests/static-analysis/ownership/owned.cpp Reviewed owned-source fixture.
tests/static-analysis/negative/cppcheck.cpp Reviewed Cppcheck failure fixture.
tests/static-analysis/negative/clang_tidy.cpp Reviewed clang-tidy failure fixture.
tests/static-analysis/negative/clang_analyzer.cpp Reviewed clang-analyzer failure fixture.
tests/hardening/probes/clean.cpp Reviewed clean hardening probe.
src/core/contract/laghu/core/identifiers.hpp Critical, 1 vote: Deleting the private default constructor makes StrongIdentifier non-trivial and breaks an existing static_assert; retain the defaulted constructor.
CMakeLists.txt Reviewed module and test registration.
cmake/static-analysis/cppcheck-2.13.txt Reviewed Cppcheck configuration.
cmake/static-analysis/clang-tidy-19.yaml Moderate, 1 vote: Enable floating-point narrowing diagnostics or use a default-enabled narrowing fixture.
cmake/static-analysis/clang-analyzer-19.txt Reviewed clang-analyzer configuration.
cmake/RunStaticAnalysis.cmake Critical, 1 vote: The src/* Cppcheck regex can select no files and bypass the gate. Moderate, 1 vote: scan-build omits profile-specific targets such as laghu_crypto.
cmake/LaghuToolchain.cmake Critical, 1 vote: Apply -fPIE only to executable targets, not shared libraries. Moderate, 2 votes: Preserve sanitizer link options for shared/module targets.
cmake/LaghuStaticAnalysis.cmake Reviewed static-analysis configuration.
cmake/LaghuHardening.cmake Critical, 2 votes: RELRO and immediate-binding probes do not validate executable linking when the toolchain uses static-library try-compiles; temporarily use executable try-compiles for these probes.
cmake/LaghuBuildIdentity.cmake Reviewed hardening metadata integration.
cmake/HardeningUnsupportedFixture.cmake Reviewed unsupported-hardening fixture.
cmake/HardeningFailureFixture.cmake Reviewed hardening-failure fixture.
cmake/ExpectStaticAnalysisOwnership.cmake Critical, 1 vote: The invalid src/* Cppcheck glob can exclude the owned file; use a matching regular expression such as src/.*.
cmake/ExpectStaticAnalysisFailure.cmake Reviewed static-analysis failure expectations.
cmake/ExpectHardeningUnsupported.cmake Reviewed unsupported-hardening expectations.
cmake/ExpectHardeningMetadata.cmake Moderate, 1 vote: Release-mode validation should require every supported hardening feature to have enabled=true.
cmake/ExpectHardeningFailure.cmake Reviewed hardening-failure expectations.
.github/workflows/toolchain.yml Reviewed CI analysis and hardening coverage.
Review details

Suppressed comments (6)

cmake/ExpectHardeningMetadata.cmake:24

  • This assertion only rejects enabled=true when supported=false; it never requires a supported feature to be enabled in a Release build. A regression that drops -fPIE, stack protection, or linker hardening while leaving the probes successful would therefore pass the metadata test. Add a Release-mode assertion that every supported feature has enabled=true.
    if("${enabled_value}" STREQUAL "true" AND NOT "${supported_value}" STREQUAL "true")
      message(FATAL_ERROR "Laghu hardening metadata expectation failed: feature=${feature}; enabled_without_support")
    endif()

cmake/LaghuHardening.cmake:56

  • On ELF targets this probe only compiles with -fPIE, but the implementation later adds -pie to executable link options. A toolchain can accept the compiler flag while rejecting the linker flag, so configuration records PIE as supported and the Release build then fails at link time (or does not validate the promised link hardening). Include the ELF-only -pie in this probe while retaining the compile-only probe on Darwin.
    laghu_hardening_probe(pie pie_supported COMPILE_OPTIONS -fPIE)

cmake/LaghuHardening.cmake:60

  • The fortification probe compiles an empty source, so -D_FORTIFY_SOURCE=3 is accepted merely as an arbitrary preprocessor definition; it never includes or exercises a fortified libc operation. This records fortification as supported and enables the flag even on POSIX platforms whose C library does not implement it, defeating the explicit unsupported-platform metadata. Probe a real fortified operation or classify support using platform/toolchain-specific checks.
    laghu_hardening_probe(fortification fortification_supported
      COMPILE_OPTIONS -O2 -D_FORTIFY_SOURCE=3)

cmake/RunStaticAnalysis.cmake:66

  • The analyzer build is hard-coded to MINIMAL, while the clang-tidy/cppcheck source list is derived from the active compile database. Optional first-party sources such as src/adapters/crypto_provider.cpp and src/adapters/entropy.cpp are only materialized for the TLS feature, so the default CI gate silently omits them from all static analysis. Pass an analysis profile that materializes every owned source or provide a dedicated all-owned-source compilation database.
  -DLAGHU_BUILD_PROFILE=MINIMAL)

cmake/RunStaticAnalysis.cmake:81

  • Even apart from the forced MINIMAL profile, scan-build only builds laghu_core, laghu_os, and laghu; profile-specific targets such as laghu_crypto are never passed to the analyzer build. This leaves those first-party translation units unanalysed by clang-analyzer while the other two tools inspect them from the compile database.
execute_process(
  COMMAND "${SCAN_BUILD}" --use-cc "${CLANG_ANALYZER}" --use-c++ "${CXX}" ${analyzer_options}
    "${CMAKE_COMMAND}" --build "${analyzer_build}" --target laghu_core laghu_os laghu

cmake/static-analysis/clang-tidy-19.yaml:5

  • bugprone-narrowing-conversions does not enable floating-point narrowing diagnostics by default in clang-tidy 19, but both the negative fixture and the ownership fixture rely on int value = 1.5 being rejected. These validation tests can therefore fail with no diagnostic, and the analysis gate will not exercise the seeded defect. Enable WarnOnFloatingPointNarrowingConversion (or change the fixtures to a default-enabled narrowing case).
  bugprone-narrowing-conversions,
  • Files reviewed: 24/24 changed files
  • Comments generated: 6
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmake/ExpectStaticAnalysisOwnership.cmake
Comment thread cmake/LaghuHardening.cmake
Comment thread cmake/LaghuToolchain.cmake
Comment thread cmake/RunStaticAnalysis.cmake
Comment thread src/core/contract/laghu/core/identifiers.hpp
Comment thread cmake/LaghuToolchain.cmake Outdated
Copilot AI review requested due to automatic review settings September 12, 2026 16:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved hardening and static-analysis findings include one critical issue and four moderate issues.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (4)

cmake/ExpectStaticAnalysisOwnership.cmake:90

  • This analyzer fixture only demonstrates that scan-build reports a defect when it is explicitly given the vendor file; it never exercises the ownership filtering used by RunStaticAnalysis.cmake (the compile-database src/ selection and _deps exclusion). A regression that feeds third-party compile entries into the production analyzer would therefore still pass this ownership test. Add a mixed owned/vendor compile database or equivalent assertion that the vendor command is not analyzed.
execute_process(
  COMMAND "${SCAN_BUILD}" --use-cc "${CLANG_ANALYZER}" --use-c++ "${CLANG_ANALYZER}"
    --status-bugs -o "${WORK_DIRECTORY}/scan-unowned" "${CLANG_ANALYZER}" -std=c++23 -c
    "${WORK_DIRECTORY}/_deps/vendor-src/src/analyzer.cpp" -o "${WORK_DIRECTORY}/analyzer.o"

cmake/LaghuHardening.cmake:148

  • Appending -O2 to every Release target changes the optimization level from CMake's normal Release setting (typically -O3) and can silently downgrade the produced binaries. Keep -O2 in the probe if needed to validate fortification, but apply only _FORTIFY_SOURCE to targets so the existing Release optimization is preserved.
      list(APPEND common_compile_options -O2 -D_FORTIFY_SOURCE=3)

cmake/LaghuHardening.cmake:84

  • This probe can report fortification support on platforms whose libc does not implement it. try_compile only verifies that -O2 and the _FORTIFY_SOURCE macro are accepted; the safe memcpy does not require a fortified implementation, so the probe succeeds even when the macro is ignored. Release metadata can therefore claim fortification is enabled and add a no-op hardening flag. Please probe an actual libc/compiler fortify marker or otherwise verify a fortified call before enabling this feature.
    laghu_hardening_probe(fortification fortification_supported
      SOURCE "${CMAKE_SOURCE_DIR}/tests/hardening/probes/fortification.cpp"
      COMPILE_OPTIONS -O2 -D_FORTIFY_SOURCE=3)

cmake/LaghuHardening.cmake:56

  • Release detection relies only on CMAKE_BUILD_TYPE. The top-level generator check also accepts Ninja Multi-Config (CMakeLists.txt:16), where this variable is empty during configure; a later cmake --build --config Release therefore skips all hardening flags and the Release failure checks. Either reject multi-config Ninja or generate configuration-specific hardening properties and validation.
  if(CMAKE_BUILD_TYPE STREQUAL "Release")
  • Files reviewed: 25/25 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cmake/LaghuToolchain.cmake
Copilot AI review requested due to automatic review settings September 12, 2026 16:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Five unresolved moderate findings affect build correctness, verification coverage, metadata, and repeatable testing.

Review details

Suppressed comments (5)

Previously missed (1) — in code that hasn't changed since the last review.

cmake/RunStaticAnalysis.cmake:66

  • Taking only the basename discards a custom or absolute compiler path. With CMAKE_CXX_COMPILER=/opt/llvm/bin/clang++, line 73 invokes clang++ through PATH instead of the configured compiler, so scan-build can fail or analyze with a different compiler.

CMakeLists.txt:309

  • This creates laghu_static_analysis as a standalone target, but it is not added to laghu_verify_toolchain's DEPENDS (see the gate at CMakeLists.txt:345-349). As a result, the documented verification target can pass without analyzing production sources; the CI step's separate build of this target does not fix the normal gate for other callers. Wire this target into the verification target whenever LAGHU_STATIC_ANALYSIS is enabled.
laghu_add_static_analysis_target()

cmake/ExpectSingleConfigNinja.cmake:7

  • The test reuses the same binary directory without clearing it. On a second ctest run, CMake sees the existing Ninja Multi-Config cache and fails with a generator-mismatch diagnostic before the project emits single-config Ninja generator, so this expectation becomes spuriously failing instead of remaining repeatable.
  COMMAND "${CMAKE_COMMAND}" -S "${SOURCE}" -B "${BINARY}" -G "Ninja Multi-Config"

cmake/LaghuHardening.cmake:174

  • static_pic is probed, required for Release builds, and applied to static/object targets, but it is omitted from the metadata members assembled here (and from the metadata validation list). Consumers therefore cannot tell whether this required hardening is supported or enabled, and unsupported static-PIC platforms are not reported in the advertised hardening metadata.
  laghu_hardening_feature_json(pie_json pie "${pie_supported}" "${pie_enabled}")
  laghu_hardening_feature_json(stack_protection_json stack_protection "${stack_protection_supported}" "${stack_protection_enabled}")
  laghu_hardening_feature_json(relro_json relro "${relro_supported}" "${relro_enabled}")
  laghu_hardening_feature_json(immediate_binding_json immediate_binding "${immediate_binding_supported}" "${immediate_binding_enabled}")
  laghu_hardening_feature_json(fortification_json fortification "${fortification_supported}" "${fortification_enabled}")

src/core/contract/laghu/core/identifiers.hpp:63

  • Deleting the only default constructor makes StrongIdentifier fail the existing std::is_trivial_v checks in has_strong_identifier_representation() and tests/core/strong_identifiers.cpp, so every build that includes this header is rejected. The constructor is already private, so keeping it defaulted still prevents public default construction while preserving the required trivial representation.
  StrongIdentifier() = delete;
  • Files reviewed: 26/26 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add static analysis and binary hardening Establish deterministic tests and analysis gates

3 participants