From c4dfe7f9e837cee36cc6294456b569fb6cf96aa5 Mon Sep 17 00:00:00 2001 From: rahulsasingh Date: Wed, 29 Apr 2026 09:50:40 +0200 Subject: [PATCH 1/2] Add CodeQL MISRA/CERT C++ analysis workflow --- .github/workflows/codeql.yml | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..0037d2b6 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,81 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +name: CodeQL Static Analysis + +on: + pull_request: + types: [opened, reopened, synchronize] + merge_group: + types: [checks_requested] + push: + branches: + - main + workflow_dispatch: + schedule: + - cron: "0 6 * * 1" + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + codeql-analysis: + name: CodeQL MISRA/CERT C++ Analysis + runs-on: ubuntu-latest + + permissions: + security-events: write + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4.2.2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: cpp + packs: codeql/misra-cpp-coding-standards,codeql/cert-cpp-coding-standards + trap-caching: false + - name: Setup Bazel + uses: bazel-contrib/setup-bazel@0.15.0 + with: + bazelisk-version: 1.26.0 + repository-cache: true + bazelisk-cache: true + + - name: Build with Bazel (CodeQL traces compiler calls) + run: | + bazel build \ + --lockfile_mode=error \ + --config x86_64-linux \ + --nouse_action_cache \ + --disk_cache= \ + --noremote_accept_cached \ + --noremote_upload_local_results \ + //... + + - name: Run CodeQL analysis + uses: github/codeql-action/analyze@v4 + with: + category: cpp-misra-cert + output: _sca + upload: true + + - name: Upload SARIF artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: codeql-results + path: _sca/ + retention-days: 30 From fff55a0ed8d9c1eee313b1395b24ff769711c947 Mon Sep 17 00:00:00 2001 From: rahulsasingh Date: Mon, 4 May 2026 09:52:36 +0200 Subject: [PATCH 2/2] test: touch C++ file to trigger CodeQL diff-informed analysis --- .github/workflows/codeql.yml | 10 +- examples/codeql/BUILD | 23 ++++ examples/codeql/misra_cert_violations.cpp | 137 ++++++++++++++++++++++ 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 examples/codeql/BUILD create mode 100644 examples/codeql/misra_cert_violations.cpp diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0037d2b6..a313514d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -46,6 +46,7 @@ jobs: with: languages: cpp packs: codeql/misra-cpp-coding-standards,codeql/cert-cpp-coding-standards + queries: security-and-quality trap-caching: false - name: Setup Bazel uses: bazel-contrib/setup-bazel@0.15.0 @@ -54,6 +55,11 @@ jobs: repository-cache: true bazelisk-cache: true + # Build the whole codebase. --keep_going lets CodeQL collect findings + # from every target that compiles even if one external dep (e.g. the + # flaky archive.ubuntu.com libacl1-dev download) fails to fetch. + # Cache flags are mandatory: cached actions skip compilation entirely + # and become invisible to CodeQL's LD_PRELOAD tracing. - name: Build with Bazel (CodeQL traces compiler calls) run: | bazel build \ @@ -63,7 +69,9 @@ jobs: --disk_cache= \ --noremote_accept_cached \ --noremote_upload_local_results \ - //... + --keep_going \ + //... \ + || echo "Build had failures (expected when external downloads time out); continuing so CodeQL can analyze what compiled." - name: Run CodeQL analysis uses: github/codeql-action/analyze@v4 diff --git a/examples/codeql/BUILD b/examples/codeql/BUILD new file mode 100644 index 00000000..51d24a02 --- /dev/null +++ b/examples/codeql/BUILD @@ -0,0 +1,23 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Compilation target so CodeQL can trace the file and report findings. +# `copts = ["-w"]` disables compiler warnings — the file deliberately violates +# rules. Without -w, `warnings_as_errors` from the project .bazelrc would fail +# the build before CodeQL can analyze it. +# Do NOT use this binary in production or test pipelines. +cc_binary( + name = "misra_cert_violations", + srcs = ["misra_cert_violations.cpp"], + copts = ["-w"], +) diff --git a/examples/codeql/misra_cert_violations.cpp b/examples/codeql/misra_cert_violations.cpp new file mode 100644 index 00000000..05a4f770 --- /dev/null +++ b/examples/codeql/misra_cert_violations.cpp @@ -0,0 +1,137 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +// This file is intentionally written with MISRA C++ and CERT C++ violations +// so the CodeQL analysis workflow has something to detect on the PR diff. +// Each violation below is paired with the CodeQL query rule ID expected to +// fire for it. DO NOT use any of these patterns in production code. +// +// NOTE: C headers ( etc.) are used intentionally instead of C++ +// headers ( etc.). CodeQL's security library models are keyed on +// global C-linkage names (::scanf, ::strcpy, ::malloc). When is +// used, calls like std::scanf bind to a different Function entity in CodeQL's +// AST that the security models do not cover. Using C headers ensures every +// call resolves to the modeled global C function. + +#include +#include +#include + +// ---- 1. cpp/scan-vulnerable ------------------------------------------------- +// Unbounded %s in scanf — classic stack buffer overflow path. +extern "C" void cwe_scan_vulnerable() +{ + char buf[8]; + scanf("%s", buf); // CodeQL: cpp/scan-vulnerable / cpp/cwe-120 + printf("%s\n", buf); +} + +// ---- 2. cpp/missing-check-against-null -------------------------------------- +// malloc result dereferenced without null check. +extern "C" void cwe_null_dereference() +{ + char* buf = static_cast(malloc(16)); + buf[0] = 'A'; // CodeQL: cpp/missing-check-against-null (buf may be null) + free(buf); +} + +// ---- 3. cpp/dangerous-function (strcpy + sprintf) --------------------------- +extern "C" void cwe_dangerous_functions(const char* user_input) +{ + char small[4]; + strcpy(small, user_input); // CodeQL: cpp/dangerous-function (strcpy) + char fmt_buf[8]; + sprintf(fmt_buf, "%s", user_input); // CodeQL: cpp/dangerous-function (sprintf) + printf("%s/%s\n", small, fmt_buf); +} + +// ---- 4. cpp/return-stack-allocated-memory ----------------------------------- +// Returning pointer to local variable. +extern "C" const char* cwe_return_stack_address() +{ + char local[16]; + sprintf(local, "stack-data"); + return local; // CodeQL: cpp/return-stack-allocated-memory +} + +// ---- 5. cpp/uninitialized-local --------------------------------------------- +extern "C" int cwe_uninitialized_local(int seed) +{ + int x; // not initialized + if (seed > 0) { + x = seed * 2; + } + return x + 1; // CodeQL: cpp/uninitialized-local (when seed <= 0) +} + +// ---- 6. cpp/comparison-with-wider-type / cpp/sign-conversion ---------------- +extern "C" int cwe_signed_comparison(int n) +{ + unsigned int len = (unsigned int)strlen("hello"); + if (n < len) { // CodeQL: cpp/comparison-with-wider-type / signed-unsigned + return 1; + } + return 0; +} + +// ---- 7. MISRA Rule M5-2-4 / AUTOSAR A5-2-2: C-style cast -------------------- +extern "C" double misra_c_style_cast(int v) +{ + return (double)v; // MISRA: should use static_cast(v) +} + +// ---- 8. MISRA Rule M6-6-1 / AUTOSAR A6-6-1: goto --------------------------- +extern "C" int misra_goto(int x) +{ + if (x < 0) { + goto err; // MISRA: goto shall not be used + } + return x; +err: + return -1; +} + +// ---- 9. CERT MEM50-CPP / cpp/use-after-free -------------------------------- +extern "C" int cwe_use_after_free() +{ + char* p = static_cast(malloc(16)); + if (p == nullptr) return 0; + free(p); + return p[0]; // CodeQL: cpp/use-after-free +} + +// ---- 10. CERT EXP34-C: pointer arithmetic out of bounds -------------------- +extern "C" void cwe_out_of_bounds_write(int n) +{ + char buf[4]; + for (int i = 0; i <= n; ++i) { // off-by-one: i can equal n + buf[i] = static_cast(i); + } + printf("%s\n", buf); +} + +int main() +{ + cwe_scan_vulnerable(); + cwe_null_dereference(); + cwe_dangerous_functions("attacker-controlled-long-string"); + auto* dangling = cwe_return_stack_address(); + printf("%p\n", static_cast(dangling)); + (void)cwe_uninitialized_local(-1); + (void)cwe_signed_comparison(-5); + (void)misra_c_style_cast(42); + (void)misra_goto(-1); + (void)cwe_use_after_free(); + cwe_out_of_bounds_write(10); + return 0; +}