ci: Drop codeql workflow

After analyzing all 218 CodeQL alerts across the project's history, the
workflow has not justified its CI cost:

- The most impactful query (PotentiallyDangerousFunction) was a custom
  systemd-specific query that has already been replaced by clang-tidy's
  bugprone-unsafe-functions check (6fb5ec3dd1).

- Of the remaining C++ queries, 6 never triggered at all
  (bad-strncpy-size, unsafe-strcat, unsafe-strncat,
  suspicious-pointer-scaling, suspicious-pointer-scaling-void,
  inconsistent-null-check).

- Several high-value-sounding queries had extreme false positive rates:
  toctou-race-condition (95% FP), use-after-free (88% FP),
  cleartext-transmission (100% FP).

- Many queries that did trigger are already covered by compiler warnings
  (-Wshadow, -Wformat, -Wunused-variable, -Wreturn-type,
  -Wtautological-compare) or existing clang-tidy checks
  (bugprone-sizeof-expression).

- Across all alerts, only 3 genuinely useful C++ fixes can be
  attributed to CodeQL: 1 tainted-format-string, 2
  incorrectly-checked-scanf. The rest were either false positives or
  incidental fixes during refactoring that weren't prompted by CodeQL.

- The Python queries are largely superseded by ruff (already in CI) and
  had an 89% false positive rate on the security-focused checks.

The workflow consumed significant CI resources (40+ minutes per run) and
the ongoing maintenance burden of triaging false positives outweighs the
marginal value of the 2-3 real findings it produced across its entire
lifetime.
This commit is contained in:
Daan De Meyer
2026-03-24 17:55:26 +01:00
committed by Zbigniew Jędrzejewski-Szmek
parent f498a5652f
commit 53d5f5c02f
7 changed files with 0 additions and 314 deletions
-12
View File
@@ -1,12 +0,0 @@
---
# vi: ts=2 sw=2 et:
# SPDX-License-Identifier: LGPL-2.1-or-later
name: "CodeQL config"
disable-default-queries: false
queries:
- name: Enable possibly useful queries which are disabled by default
uses: ./.github/codeql-custom.qls
- name: systemd-specific CodeQL queries
uses: ./.github/codeql-queries/
-44
View File
@@ -1,44 +0,0 @@
---
# vi: ts=2 sw=2 et syntax=yaml:
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Note: it is not recommended to directly reference the respective queries from
# the github/codeql repository, so we have to "dance" around it using
# a custom QL suite
# See:
# - https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#running-additional-queries
# - https://github.com/github/codeql-action/issues/430#issuecomment-806092120
# - https://codeql.github.com/docs/codeql-cli/creating-codeql-query-suites/
# Note: the codeql/<lang>-queries pack name can be found in the CodeQL repo[0]
# in <lang>/ql/src/qlpack.yml. The respective codeql-suites are then
# under <lang>/ql/src/codeql-suites/.
#
# [0] https://github.com/github/codeql
- import: codeql-suites/cpp-lgtm.qls
from: codeql/cpp-queries
- import: codeql-suites/python-lgtm.qls
from: codeql/python-queries
- include:
id:
- cpp/bad-strncpy-size
- cpp/declaration-hides-variable
- cpp/include-non-header
- cpp/inconsistent-null-check
- cpp/mistyped-function-arguments
- cpp/nested-loops-with-same-variable
- cpp/sizeof-side-effect
- cpp/suspicious-pointer-scaling
- cpp/suspicious-pointer-scaling-void
- cpp/suspicious-sizeof
- cpp/unsafe-strcat
- cpp/unsafe-strncat
- cpp/unsigned-difference-expression-compared-zero
- cpp/unused-local-variable
tags:
- "security"
- "correctness"
severity: "error"
- exclude:
id:
- cpp/fixme-comment
@@ -1,110 +0,0 @@
/**
* vi: sw=2 ts=2 et syntax=ql:
*
* Based on cpp/uninitialized-local.
*
* @name Potentially uninitialized local variable using the cleanup attribute
* @description Running the cleanup handler on a possibly uninitialized variable
* is generally a bad idea.
* @id cpp/uninitialized-local-with-cleanup
* @kind problem
* @problem.severity error
* @precision high
* @tags security
*/
import cpp
import semmle.code.cpp.controlflow.StackVariableReachability
/** Auxiliary predicate: List cleanup functions we want to explicitly ignore
* since they don't do anything illegal even when the variable is uninitialized
*/
predicate cleanupFunctionDenyList(string fun) {
fun = "erase_char"
}
/**
* A declaration of a local variable using __attribute__((__cleanup__(x)))
* that leaves the variable uninitialized.
*/
DeclStmt declWithNoInit(LocalVariable v) {
result.getADeclaration() = v and
not v.hasInitializer() and
/* The variable has __attribute__((__cleanup__(...))) set */
v.getAnAttribute().hasName("cleanup") and
/* Check if the cleanup function is not on a deny list */
not cleanupFunctionDenyList(v.getAnAttribute().getAnArgument().getValueText())
}
class UninitialisedLocalReachability extends StackVariableReachability {
UninitialisedLocalReachability() { this = "UninitialisedLocal" }
override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
/* Note: _don't_ use the `useOfVarActual()` predicate here (and a couple of lines
* below), as it assumes that the callee always modifies the variable if
* it's passed to the function.
*
* i.e.:
* _cleanup_free char *x;
* fun(&x);
* puts(x);
*
* `useOfVarActual()` won't treat this as an uninitialized read even if the callee
* doesn't modify the argument, however, `useOfVar()` will
*/
override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVar(v, node) }
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
/* only report the _first_ possibly uninitialized use */
useOfVar(v, node) or
(
/* If there's a return statement somewhere between the variable declaration
* and a possible definition, don't accept is as a valid initialization.
*
* E.g.:
* _cleanup_free_ char *x;
* ...
* if (...)
* return;
* ...
* x = malloc(...);
*
* is not a valid initialization, since we might return from the function
* _before_ the actual initialization (emphasis on _might_, since we
* don't know if the return statement might ever evaluate to true).
*/
definitionBarrier(v, node) and
not exists(ReturnStmt rs |
/* The attribute check is "just" a complexity optimization */
v.getFunction() = rs.getEnclosingFunction() and v.getAnAttribute().hasName("cleanup") |
rs.getLocation().isBefore(node.getLocation())
)
)
}
}
pragma[noinline]
predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
/**
* Auxiliary predicate: List common exceptions or false positives
* for this check to exclude them.
*/
VariableAccess commonException() {
/* If the uninitialized use we've found is in a macro expansion, it's
* typically something like va_start(), and we don't want to complain. */
result.getParent().isInMacroExpansion()
or
result.getParent() instanceof BuiltInOperation
or
/* Finally, exclude functions that contain assembly blocks. It's
* anyone's guess what happens in those. */
containsInlineAssembly(result.getEnclosingFunction())
}
from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va
where
r.reaches(_, v, va) and
not va = commonException()
select va, "The variable $@ may not be initialized here, but has a cleanup handler.", v, v.getName()
-11
View File
@@ -1,11 +0,0 @@
---
# vi: ts=2 sw=2 et syntax=yaml:
# SPDX-License-Identifier: LGPL-2.1-or-later
library: false
name: systemd/cpp-queries
version: 0.0.1
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"
extractor: cpp
-68
View File
@@ -1,68 +0,0 @@
---
# vi: ts=2 sw=2 et:
# SPDX-License-Identifier: LGPL-2.1-or-later
#
name: "CodeQL"
on:
pull_request:
branches:
- main
- v[0-9]+-stable
paths:
- '**/meson.build'
- '.github/**/codeql*'
- 'src/**'
- 'test/**'
- 'tools/**'
push:
branches:
- main
- v[0-9]+-stable
permissions:
contents: read
jobs:
analyze:
name: Analyze
if: github.repository != 'systemd/systemd-security'
runs-on: ubuntu-24.04
concurrency:
group: ${{ github.workflow }}-${{ matrix.language }}-${{ github.ref }}
cancel-in-progress: true
permissions:
actions: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ['cpp', 'python']
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql-config.yml
- run: |
sudo -E .github/workflows/unit-tests.sh SETUP
# TODO: drop after we switch to ubuntu 26.04
bpftool_binary=$(find /usr/lib/linux-tools/ /usr/lib/linux-tools-* -name 'bpftool' -perm /u=x 2>/dev/null | sort -r | head -n1)
if [ -n "$bpftool_binary" ]; then
sudo rm -f /usr/{bin,sbin}/bpftool
sudo ln -s "$bpftool_binary" /usr/bin/
fi
- name: Autobuild
uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e
-4
View File
@@ -70,10 +70,6 @@ available functionality:
13. When building systemd from a git checkout the build scripts will
automatically enable a git commit hook that ensures whitespace cleanliness.
14. [CodeQL](https://codeql.github.com/) analyzes each PR and every commit
pushed to `main`. The list of active alerts can be found
[here](https://github.com/systemd/systemd/security/code-scanning).
15. Each PR is automatically tested with [Address Sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
and [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html).
See [Testing systemd using sanitizers](/TESTING_WITH_SANITIZERS)
-65
View File
@@ -339,71 +339,6 @@ where `--test-name=` is the name of the test you want to run/debug. The
`--shell-fail` option will pause the execution in case the test fails and shows
you the information how to connect to the testbed for further debugging.
## Manually running CodeQL analysis
This is mostly useful for debugging various CodeQL quirks.
Download the CodeQL Bundle from https://github.com/github/codeql-action/releases
and unpack it somewhere. From now the 'tutorial' assumes you have the `codeql`
binary from the unpacked archive in $PATH for brevity.
Switch to the systemd repository if not already:
```shell
$ cd <systemd-repo>
```
Create an initial CodeQL database:
```shell
$ CCACHE_DISABLE=1 codeql database create codeqldb --language=cpp -vvv
```
Disabling ccache is important, otherwise you might see CodeQL complaining:
No source code was seen and extracted to
/home/mrc0mmand/repos/@ci-incubator/systemd/codeqldb. This can occur if the
specified build commands failed to compile or process any code.
- Confirm that there is some source code for the specified language in the
project.
- For codebases written in Go, JavaScript, TypeScript, and Python, do not
specify an explicit --command.
- For other languages, the --command must specify a "clean" build which
compiles all the source code files without reusing existing build artefacts.
If you want to run all queries systemd uses in CodeQL, run:
```shell
$ codeql database analyze codeqldb/ --format csv --output results.csv .github/codeql-custom.qls .github/codeql-queries/*.ql -vvv
```
Note: this will take a while.
If you're interested in a specific check, the easiest way (without hunting down
the specific CodeQL query file) is to create a custom query suite. For example:
```shell
$ cat >test.qls <<EOF
- queries: .
from: codeql/cpp-queries
- include:
id:
- cpp/missing-return
EOF
```
And then execute it in the same way as above:
```shell
$ codeql database analyze codeqldb/ --format csv --output results.csv test.qls -vvv
```
More about query suites here: https://codeql.github.com/docs/codeql-cli/creating-codeql-query-suites/
The results are then located in the `results.csv` file as a comma separated
values list (obviously), which is the most human-friendly output format the
CodeQL utility provides (so far).
## Running Coverity locally
Note: this requires a Coverity license, as the public tool