summaryrefslogtreecommitdiffstats
path: root/.github
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:49:52 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:49:52 +0000
commit55944e5e40b1be2afc4855d8d2baf4b73d1876b5 (patch)
tree33f869f55a1b149e9b7c2b7e201867ca5dd52992 /.github
parentInitial commit. (diff)
downloadsystemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.tar.xz
systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.zip
Adding upstream version 255.4.upstream/255.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml184
-rw-r--r--.github/ISSUE_TEMPLATE/config.yml9
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.yml125
-rw-r--r--.github/advanced-issue-labeler.yml149
-rw-r--r--.github/codeql-config.yml12
-rw-r--r--.github/codeql-custom.qls44
-rw-r--r--.github/codeql-queries/PotentiallyDangerousFunction.ql59
-rw-r--r--.github/codeql-queries/UninitializedVariableWithCleanup.ql110
-rw-r--r--.github/codeql-queries/qlpack.yml11
-rw-r--r--.github/dependabot.yml19
-rw-r--r--.github/development-freeze.yml12
-rw-r--r--.github/labeler.yml140
-rwxr-xr-x.github/workflows/build_test.sh161
-rw-r--r--.github/workflows/build_test.yml38
-rw-r--r--.github/workflows/cflite_pr.yml39
-rw-r--r--.github/workflows/cifuzz.yml74
-rw-r--r--.github/workflows/codeql.yml59
-rw-r--r--.github/workflows/coverity.yml30
-rw-r--r--.github/workflows/development_freeze.yml74
-rw-r--r--.github/workflows/differential-shellcheck.yml35
-rw-r--r--.github/workflows/gather-pr-metadata.yml37
-rw-r--r--.github/workflows/issue_labeler.yml36
-rw-r--r--.github/workflows/labeler.yml119
-rw-r--r--.github/workflows/linter.yml36
-rw-r--r--.github/workflows/make_release.yml24
-rw-r--r--.github/workflows/mkosi.yml143
-rw-r--r--.github/workflows/requirements.txt19
-rw-r--r--.github/workflows/scorecards.yml41
-rwxr-xr-x.github/workflows/unit_tests.sh123
-rw-r--r--.github/workflows/unit_tests.yml45
31 files changed, 2008 insertions, 0 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..b720b58
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: ['https://spi-inc.org/projects/systemd/']
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..06a8640
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,184 @@
+name: Bug Report
+description: A report of an error in a recent systemd version
+labels: ["bug 🐛"]
+
+body:
+ - type: markdown
+ attributes:
+ value: Thanks for taking the time to fill out this bug report!
+
+ - type: input
+ id: version
+ attributes:
+ label: systemd version the issue has been seen with
+ description: |
+ Do not submit bug reports about anything but the two most recently released *major* systemd versions upstream!
+ If there have been multiple stable releases for that major version, please consider updating to a recent one before reporting an issue.
+ When using a distro package, please make sure that the version reported is meaningful for upstream.
+ If a distro build is used, please just paste the package version, e.g. `systemd-253-6.fc38.x86_64`.
+ See https://github.com/systemd/systemd-stable/tags for the list of most recent releases.
+ For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues).
+ placeholder: '253'
+ validations:
+ required: true
+
+ - type: input
+ id: distro
+ attributes:
+ label: Used distribution
+ description: Used distribution and its version
+ placeholder: Fedora 38
+ validations:
+ required: false
+
+ - type: input
+ id: kernel
+ attributes:
+ label: Linux kernel version used
+ description: |
+ Please use `uname -r` to get linux kernel version.
+ placeholder: kernel-6.2.5-300.fc38.x86_64
+ validations:
+ required: false
+
+ - type: dropdown
+ id: architecture
+ attributes:
+ label: CPU architectures issue was seen on
+ options:
+ - aarch64
+ - alpha
+ - arm
+ - i686
+ - ia64
+ - loongarch
+ - mips
+ - parisc
+ - ppc (big endian)
+ - ppc64 (big endian)
+ - ppc64le
+ - riscv64
+ - s390x
+ - sparc
+ - sparc64
+ - x86_64
+ - other
+ validations:
+ required: false
+
+ - type: dropdown
+ id: component
+ attributes:
+ label: Component
+ description: Please chose components related to this issue.
+ multiple: true
+ # When updating list of components please also update labeling policy
+ # policy: `.github/advanced-issue-labeler.yml`
+ options:
+ - 'bootctl'
+ - 'coredumpctl'
+ - 'homectl'
+ - 'hostnamectl'
+ - 'hardware database files'
+ - 'journalctl'
+ - 'kernel-install'
+ - 'loginctl'
+ - 'machinectl'
+ - 'networkctl'
+ - 'nss-resolve'
+ - 'oomctl'
+ - 'pam_systemd'
+ - 'pam_systemd_home'
+ - 'portablectl'
+ - 'resolvectl'
+ - 'rpm scriptlets'
+ - 'systemctl'
+ - 'systemd'
+ - 'systemd-analyze'
+ - 'systemd-ask-password'
+ - 'systemd-binfmt'
+ - 'systemd-boot'
+ - 'systemd-cgtop'
+ - 'systemd-coredump'
+ - 'systemd-cryptsetup'
+ - 'systemd-delta'
+ - 'systemd-dissect'
+ - 'systemd-env-generator'
+ - 'systemd-fsck'
+ - 'systemd-gpt-auto-generator'
+ - 'systemd-growfs'
+ - 'systemd-homed'
+ - 'systemd-hostnamed'
+ - 'systemd-hwdb'
+ - 'systemd-import'
+ - 'systemd-journal-gatewayd'
+ - 'systemd-journal-remote'
+ - 'systemd-journal-upload'
+ - 'systemd-journald'
+ - 'systemd-logind'
+ - 'systemd-machined'
+ - 'systemd-modules-load'
+ - 'systemd-network-generator'
+ - 'systemd-networkd'
+ - 'systemd-networkd-wait-online'
+ - 'systemd-nspawn'
+ - 'systemd-oomd'
+ - 'systemd-portabled'
+ - 'systemd-pstore'
+ - 'systemd-repart'
+ - 'systemd-resolved'
+ - 'systemd-rfkill'
+ - 'systemd-run'
+ - 'systemd-stub'
+ - 'systemd-sysctl'
+ - 'systemd-sysext'
+ - 'systemd-sysusers'
+ - 'systemd-sysv-generator'
+ - 'systemd-timedate'
+ - 'systemd-timesync'
+ - 'systemd-tmpfiles'
+ - 'systemd-udevd'
+ - 'systemd-userdb'
+ - 'systemd-veritysetup'
+ - 'systemd-xdg-autostart-generator'
+ - 'timedatectl'
+ - 'udevadm'
+ - 'udev rule files'
+ - 'userdbctl'
+ - 'tests'
+ - 'other'
+ validations:
+ required: false
+
+ - type: textarea
+ id: expected-behaviour
+ attributes:
+ label: Expected behaviour you didn't see
+ validations:
+ required: false
+
+ - type: textarea
+ id: unexpected-behaviour
+ attributes:
+ label: Unexpected behaviour you saw
+ validations:
+ required: false
+
+ - type: textarea
+ id: steps-to-reproduce
+ attributes:
+ label: Steps to reproduce the problem
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional-information
+ attributes:
+ label: Additional program output to the terminal or log subsystem illustrating the issue
+ description: |
+ Please paste relevant program terminal or journal output here, ideally when generated in debug mode (try setting the `SYSTEMD_LOG_LEVEL=debug` environment variable).
+ For very long copy/pasted data consider using a service like https://gist.github.com/. Where copy/paste is not possible (for example early boot or late shutdown), a photo of the screen might do too, but text is always much preferred.
+ placeholder: This will be automatically formatted into code, so no need for backticks.
+ render: sh
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..159187e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,9 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+blank_issues_enabled: true
+contact_links:
+ - name: systemd-devel mailing list
+ url: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
+ about: Please ask (and answer) questions here, use the issue tracker only for issues.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..1413b5f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,125 @@
+name: Feature request
+description: Suggest an improvement
+labels: ["RFE 🎁"]
+
+body:
+ - type: markdown
+ attributes:
+ value: Thanks for taking the time to fill out this feature request!
+
+ - type: dropdown
+ id: component
+ attributes:
+ label: Component
+ description: Please chose components related to this feature request.
+ multiple: true
+ # When updating list of components please also update labeling policy
+ # policy: `.github/advanced-issue-labeler.yml`
+ options:
+ - 'bootctl'
+ - 'coredumpctl'
+ - 'homectl'
+ - 'hostnamectl'
+ - 'hardware database files'
+ - 'journalctl'
+ - 'kernel-install'
+ - 'loginctl'
+ - 'machinectl'
+ - 'networkctl'
+ - 'nss-resolve'
+ - 'oomctl'
+ - 'pam_systemd'
+ - 'pam_systemd_home'
+ - 'portablectl'
+ - 'resolvectl'
+ - 'rpm scriptlets'
+ - 'systemctl'
+ - 'systemd'
+ - 'systemd-analyze'
+ - 'systemd-ask-password'
+ - 'systemd-binfmt'
+ - 'systemd-boot'
+ - 'systemd-cgtop'
+ - 'systemd-coredump'
+ - 'systemd-cryptsetup'
+ - 'systemd-delta'
+ - 'systemd-dissect'
+ - 'systemd-env-generator'
+ - 'systemd-fsck'
+ - 'systemd-gpt-auto-generator'
+ - 'systemd-growfs'
+ - 'systemd-homed'
+ - 'systemd-hostnamed'
+ - 'systemd-hwdb'
+ - 'systemd-import'
+ - 'systemd-journal-gatewayd'
+ - 'systemd-journal-remote'
+ - 'systemd-journal-upload'
+ - 'systemd-journald'
+ - 'systemd-logind'
+ - 'systemd-machined'
+ - 'systemd-modules-load'
+ - 'systemd-network-generator'
+ - 'systemd-networkd'
+ - 'systemd-networkd-wait-online'
+ - 'systemd-nspawn'
+ - 'systemd-oomd'
+ - 'systemd-portabled'
+ - 'systemd-pstore'
+ - 'systemd-repart'
+ - 'systemd-resolved'
+ - 'systemd-rfkill'
+ - 'systemd-run'
+ - 'systemd-stub'
+ - 'systemd-sysctl'
+ - 'systemd-sysext'
+ - 'systemd-sysusers'
+ - 'systemd-sysv-generator'
+ - 'systemd-timedate'
+ - 'systemd-timesync'
+ - 'systemd-tmpfiles'
+ - 'systemd-udevd'
+ - 'systemd-userdb'
+ - 'systemd-veritysetup'
+ - 'systemd-xdg-autostart-generator'
+ - 'timedatectl'
+ - 'udevadm'
+ - 'udev rule files'
+ - 'userdbctl'
+ - 'tests'
+ - 'other'
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Is your feature request related to a problem? Please describe
+ description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+ validations:
+ required: false
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Describe the solution you'd like
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: false
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Describe alternatives you've considered
+ description: A clear and concise description of any alternative solutions or features you've considered.
+ validations:
+ required: false
+
+ - type: input
+ id: version
+ attributes:
+ label: The systemd version you checked that didn't have the feature you are asking for
+ description: If this is not the most recently released upstream version, then please check first if it has that feature already.
+ placeholder: '253'
+ validations:
+ required: false
diff --git a/.github/advanced-issue-labeler.yml b/.github/advanced-issue-labeler.yml
new file mode 100644
index 0000000..e6ae5dc
--- /dev/null
+++ b/.github/advanced-issue-labeler.yml
@@ -0,0 +1,149 @@
+---
+# syntax - https://github.com/redhat-plumbers-in-action/advanced-issue-labeler#policy
+
+policy:
+ - template: [bug_report.yml, feature_request.yml]
+ section:
+ - id: [component]
+ block-list: [other]
+ label:
+ - name: analyze
+ keys: ['systemd-analyze']
+
+ - name: ask-password
+ keys: ['systemd-ask-password']
+
+ - name: binfmt
+ keys: ['systemd-binfmt']
+
+ - name: cgtop
+ keys: ['systemd-cgtop']
+
+ - name: coredump
+ keys: ['coredumpctl', 'systemd-coredump']
+
+ - name: cryptsetup
+ keys: ['systemd-cryptsetup']
+
+ - name: delta
+ keys: ['systemd-delta']
+
+ - name: dissect
+ keys: ['systemd-dissect']
+
+ - name: env
+ keys: ['systemd-env-generator']
+
+ - name: fsck
+ keys: ['systemd-fsck']
+
+ - name: gpt-auto
+ keys: ['systemd-gpt-auto-generator']
+
+ - name: growfs
+ keys: ['systemd-growfs']
+
+ - name: homed
+ keys: ['systemd-homed', 'homectl', 'pam_systemd_home']
+
+ - name: hostname
+ keys: ['systemd-hostnamed', 'hostnamectl']
+
+ - name: hwdb
+ keys: ['systemd-hwdb', 'hardware database files']
+
+ - name: import
+ keys: ['systemd-import']
+
+ - name: journal
+ keys: ['systemd-journald', 'journalctl']
+
+ - name: journal-remote
+ keys: ['systemd-journal-remote', 'systemd-journal-upload', 'systemd-journal-gatewayd']
+
+ - name: kernel-install
+ keys: ['kernel-install']
+
+ - name: logind
+ keys: ['systemd-logind', 'loginctl', 'pam_systemd']
+
+ - name: machined
+ keys: ['systemd-machined', 'machinectl']
+
+ - name: modules-load
+ keys: ['systemd-modules-load']
+
+ - name: network
+ keys: ['systemd-networkd', 'networkctl', 'systemd-networkd-wait-online', 'systemd-network-generator']
+
+ - name: nspawn
+ keys: ['systemd-nspawn']
+
+ - name: oomd
+ keys: ['systemd-oomd', 'oomctl']
+
+ - name: pid1
+ keys: ['systemd']
+
+ - name: portabled
+ keys: ['systemd-portabled', 'portablectl']
+
+ - name: pstore
+ keys: ['systemd-pstore']
+
+ - name: repart
+ keys: ['systemd-repart']
+
+ - name: resolve
+ keys: ['systemd-resolved', 'resolvectl', 'nss-resolve']
+
+ - name: rfkill
+ keys: ['systemd-rfkill']
+
+ - name: rpm
+ keys: ['rpm scriptlets']
+
+ - name: run
+ keys: ['systemd-run']
+
+ - name: sd-boot/sd-stub/bootctl
+ keys: ['bootctl', 'systemd-boot', 'systemd-stub']
+
+ - name: sysctl
+ keys: ['systemd-sysctl']
+
+ - name: sysext
+ keys: ['systemd-sysext']
+
+ - name: systemctl
+ keys: ['systemctl']
+
+ - name: sysusers
+ keys: ['systemd-sysusers']
+
+ - name: sysv
+ keys: ['systemd-sysv-generator']
+
+ - name: tests
+ keys: ['tests']
+
+ - name: timedate
+ keys: ['systemd-timedate', 'timedatectl']
+
+ - name: timesync
+ keys: ['systemd-timesync']
+
+ - name: tmpfiles
+ keys: ['systemd-tmpfiles']
+
+ - name: udev
+ keys: ['systemd-udevd', 'udevadm', 'udev rule files']
+
+ - name: userdb
+ keys: ['systemd-userdb', 'userdbctl']
+
+ - name: veritysetup
+ keys: ['systemd-veritysetup']
+
+ - name: xdg-autostart
+ keys: ['systemd-xdg-autostart-generator']
diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml
new file mode 100644
index 0000000..7c01d32
--- /dev/null
+++ b/.github/codeql-config.yml
@@ -0,0 +1,12 @@
+---
+# 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/
diff --git a/.github/codeql-custom.qls b/.github/codeql-custom.qls
new file mode 100644
index 0000000..d35fbe3
--- /dev/null
+++ b/.github/codeql-custom.qls
@@ -0,0 +1,44 @@
+---
+# 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
diff --git a/.github/codeql-queries/PotentiallyDangerousFunction.ql b/.github/codeql-queries/PotentiallyDangerousFunction.ql
new file mode 100644
index 0000000..d5a5635
--- /dev/null
+++ b/.github/codeql-queries/PotentiallyDangerousFunction.ql
@@ -0,0 +1,59 @@
+/**
+ * vi: sw=2 ts=2 et syntax=ql:
+ *
+ * Borrowed from
+ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql
+ *
+ * @name Use of potentially dangerous function
+ * @description Certain standard library functions are dangerous to call.
+ * @id cpp/potentially-dangerous-function
+ * @kind problem
+ * @problem.severity error
+ * @precision high
+ * @tags reliability
+ * security
+ */
+import cpp
+
+predicate potentiallyDangerousFunction(Function f, string message) {
+ (
+ f.getQualifiedName() = "fgets" and
+ message = "Call to fgets() is potentially dangerous. Use read_line() instead."
+ ) or (
+ f.getQualifiedName() = "strtok" and
+ message = "Call to strtok() is potentially dangerous. Use extract_first_word() instead."
+ ) or (
+ f.getQualifiedName() = "strsep" and
+ message = "Call to strsep() is potentially dangerous. Use extract_first_word() instead."
+ ) or (
+ f.getQualifiedName() = "dup" and
+ message = "Call to dup() is potentially dangerous. Use fcntl(fd, FD_DUPFD_CLOEXEC, 3) instead."
+ ) or (
+ f.getQualifiedName() = "htonl" and
+ message = "Call to htonl() is confusing. Use htobe32() instead."
+ ) or (
+ f.getQualifiedName() = "htons" and
+ message = "Call to htons() is confusing. Use htobe16() instead."
+ ) or (
+ f.getQualifiedName() = "ntohl" and
+ message = "Call to ntohl() is confusing. Use be32toh() instead."
+ ) or (
+ f.getQualifiedName() = "ntohs" and
+ message = "Call to ntohs() is confusing. Use be16toh() instead."
+ ) or (
+ f.getQualifiedName() = "strerror" and
+ message = "Call to strerror() is not thread-safe. Use printf()'s %m format string or STRERROR() instead."
+ ) or (
+ f.getQualifiedName() = "accept" and
+ message = "Call to accept() is not O_CLOEXEC-safe. Use accept4() instead."
+ ) or (
+ f.getQualifiedName() = "dirname" and
+ message = "Call dirname() is icky. Use path_extract_directory() instead."
+ )
+}
+
+from FunctionCall call, Function target, string message
+where
+ call.getTarget() = target and
+ potentiallyDangerousFunction(target, message)
+select call, message
diff --git a/.github/codeql-queries/UninitializedVariableWithCleanup.ql b/.github/codeql-queries/UninitializedVariableWithCleanup.ql
new file mode 100644
index 0000000..e514111
--- /dev/null
+++ b/.github/codeql-queries/UninitializedVariableWithCleanup.ql
@@ -0,0 +1,110 @@
+/**
+ * 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()
diff --git a/.github/codeql-queries/qlpack.yml b/.github/codeql-queries/qlpack.yml
new file mode 100644
index 0000000..a1a2dec
--- /dev/null
+++ b/.github/codeql-queries/qlpack.yml
@@ -0,0 +1,11 @@
+---
+# 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
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..3e067c1
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 2
+ - package-ecosystem: "pip"
+ directory: "/.github/workflows"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 2
+ - package-ecosystem: "docker"
+ directory: "/.clusterfuzzlite"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 2
diff --git a/.github/development-freeze.yml b/.github/development-freeze.yml
new file mode 100644
index 0000000..564e5f0
--- /dev/null
+++ b/.github/development-freeze.yml
@@ -0,0 +1,12 @@
+# syntax - https://github.com/redhat-plumbers-in-action/devel-freezer#policy
+---
+
+policy:
+ # tags like v253-rc1, v253-rc2, etc.
+ - tags: ['^\S*-rc\d+$']
+ feedback:
+ frozen-state: |
+ An -rc1 tag has been created and a release is being prepared, so please note that PRs introducing new features and APIs will be held back until the new version has been released.
+ unfreeze-state: |
+ We had successfully released a new major release. We are no longer in a development freeze phase.
+ We will try our best to get back to your PR as soon as possible. Thank you for your patience.
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 0000000..fd5fc91
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+apparmor:
+ - '**/*apparmor*'
+binfmt:
+ - '**/*binfmt*'
+btrfs:
+ - '**/*btrfs*'
+build-system:
+ - meson_options.txt
+ - '**/meson.build'
+ - Makefile
+ - configure
+busctl:
+ - '**/*busctl*'
+cgls:
+ - '**/*cgls*'
+cgtop:
+ - '**/*cgtop*'
+ci:
+ - '.github/*'
+coccinelle:
+ - coccinelle/*
+coredump:
+ - '**/*coredump*'
+documentation:
+ - NEWS
+ - README*
+ - docs/*
+ - man/*
+env-generator:
+ - '**/*environment*generator*'
+debug-generator:
+ - '**/debug-generator*'
+fstab-generator:
+ - '**/*fstab-generator*'
+growfs:
+ - '**/*growfs*'
+hwdb:
+ - hwdb.d/**/*
+journal:
+ - src/journal/*
+ - src/libsystemd/sd-journal/*
+journal-remote:
+ - src/journal-remote/*
+meson:
+ - meson_options.txt
+ - '**/meson.build'
+mkosi:
+ - .mkosi/*
+ - mkosi.build
+network:
+ - src/libsystemd-network/**/*
+ - src/network/**/*
+portable:
+ - src/portable/**/*
+rc-local-generator:
+ - src/rc-local-generator/*
+repart:
+ - '**/*repart*'
+resolve:
+ - '**/*resolve*'
+rfkill:
+ - '**/*rfkill*'
+rpm:
+ - src/rpm/*
+run:
+ - src/run/*
+ - man/systemd-run*
+sd-boot/sd-stub/bootctl:
+ - src/boot/**/*
+ - man/bootctl*
+ - man/systemd-boot.xml
+sd-bus:
+ - '**/sd-bus*/**'
+sd-daemon:
+ - '**/sd-daemon*/**'
+sd-device:
+ - '**/sd-device*/**'
+sd-event:
+ - '**/sd-event*/**'
+sd-hwdb:
+ - '**/sd-hwdb*/**'
+sd-id128:
+ - '**/sd-id128*/**'
+sd-netlink:
+ - '**/sd-netlink*/**'
+sd-path:
+ - '**/sd-path*/**'
+sd-resolve:
+ - '**/sd-resolve*/**'
+selinux:
+ - '**/*selinux*'
+sleep:
+ - '**/*sleep*'
+smack:
+ - '**/*smack*'
+socket-proxy:
+ - '**/*socket-proxy*'
+sysv-generator:
+ - '**/*sysv-generator*'
+systemctl:
+ - '**/systemctl*'
+sysupdate:
+ - '**/*sysupdate*'
+sysvcompat:
+ - '**/*sysv*'
+sysctl:
+ - '**/*sysctl*'
+timedate:
+ - '**/*timedate*'
+timesync:
+ - '**/*timesync*'
+tests:
+ - src/test/**/*
+ - src/fuzz/**/*
+ - test/**/*
+ - '**/test-*'
+ - .github/workflows/*
+tpm2:
+ - '**/*tpm2*'
+ - '**/*tpm-*'
+udev:
+ - src/udev/**/*
+ - src/libudev/*
+ - man/*udev*
+uki:
+ - '**/ukify*'
+units:
+ - units/**/*
+userdb:
+ - '**/*userdb*'
+util-lib:
+ - src/fundamental/**/*
+ - src/basic/**/*
+ - src/shared/**/*
+vconsole:
+ - '**/*vconsole*'
+xdg-autostart:
+ - '**/**xdg-autostart-generator*'
diff --git a/.github/workflows/build_test.sh b/.github/workflows/build_test.sh
new file mode 100755
index 0000000..c550046
--- /dev/null
+++ b/.github/workflows/build_test.sh
@@ -0,0 +1,161 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+set -ex
+
+info() { echo -e "\033[33;1m$1\033[0m"; }
+fatal() { echo >&2 -e "\033[31;1m$1\033[0m"; exit 1; }
+success() { echo >&2 -e "\033[32;1m$1\033[0m"; }
+
+ARGS=(
+ "--optimization=0 -Dopenssl=disabled -Dcryptolib=gcrypt -Ddns-over-tls=gnutls -Dtpm=true -Dtpm2=enabled"
+ "--optimization=s -Dutmp=false"
+ "--optimization=3 -Db_lto=true -Ddns-over-tls=false"
+ "--optimization=3 -Db_lto=false -Dtpm2=disabled -Dlibfido2=disabled -Dp11kit=disabled"
+ "--optimization=3 -Ddns-over-tls=openssl"
+ "--optimization=3 -Dfexecve=true -Dstandalone-binaries=true -Dstatic-libsystemd=true -Dstatic-libudev=true"
+ "-Db_ndebug=true"
+)
+PACKAGES=(
+ cryptsetup-bin
+ expect
+ fdisk
+ gettext
+ iputils-ping
+ isc-dhcp-client
+ itstool
+ kbd
+ libblkid-dev
+ libbpf-dev
+ libcap-dev
+ libcurl4-gnutls-dev
+ libfdisk-dev
+ libfido2-dev
+ libgpg-error-dev
+ liblz4-dev
+ liblzma-dev
+ libmicrohttpd-dev
+ libmount-dev
+ libp11-kit-dev
+ libpwquality-dev
+ libqrencode-dev
+ libssl-dev
+ libtss2-dev
+ libxen-dev
+ libxkbcommon-dev
+ libxtables-dev
+ libzstd-dev
+ # mold
+ mount
+ net-tools
+ python3-evdev
+ python3-jinja2
+ python3-lxml
+ python3-pefile
+ python3-pip
+ python3-pyelftools
+ python3-pyparsing
+ python3-setuptools
+ quota
+ strace
+ unifont
+ util-linux
+ zstd
+)
+COMPILER="${COMPILER:?}"
+COMPILER_VERSION="${COMPILER_VERSION:?}"
+LINKER="${LINKER:?}"
+CRYPTOLIB="${CRYPTOLIB:?}"
+RELEASE="$(lsb_release -cs)"
+
+# mold-2.2.0+ fixes some bugs breaking bootloader builds.
+# TODO: Switch to distro mold with ubuntu-24.04
+if [[ "$LINKER" == mold ]]; then
+ wget https://github.com/rui314/mold/releases/download/v2.2.0/mold-2.2.0-x86_64-linux.tar.gz
+ echo "d66e0230c562c2ba0e0b789cc5034e0fa2369cc843d0154920de4269cd94afeb mold-2.2.0-x86_64-linux.tar.gz" | sha256sum -c
+ sudo tar -xz -C /usr --strip-components=1 -f mold-2.2.0-x86_64-linux.tar.gz
+fi
+
+# Note: As we use postfixed clang/gcc binaries, we need to override $AR
+# as well, otherwise meson falls back to ar from binutils which
+# doesn't work with LTO
+if [[ "$COMPILER" == clang ]]; then
+ CC="clang-$COMPILER_VERSION"
+ CXX="clang++-$COMPILER_VERSION"
+ AR="llvm-ar-$COMPILER_VERSION"
+
+ # Prefer the distro version if available
+ if ! apt-get -y install --dry-run "llvm-$COMPILER_VERSION" >/dev/null; then
+ # Latest LLVM stack deb packages provided by https://apt.llvm.org/
+ # Following snippet was partly borrowed from https://apt.llvm.org/llvm.sh
+ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | \
+ sudo gpg --yes --dearmor --output /usr/share/keyrings/apt-llvm-org.gpg
+ echo "deb [signed-by=/usr/share/keyrings/apt-llvm-org.gpg] http://apt.llvm.org/$RELEASE/ llvm-toolchain-$RELEASE-$COMPILER_VERSION main" | \
+ sudo tee /etc/apt/sources.list.d/llvm-toolchain.list
+ fi
+
+ PACKAGES+=("clang-$COMPILER_VERSION" "lldb-$COMPILER_VERSION" "python3-lldb-$COMPILER_VERSION" "lld-$COMPILER_VERSION" "clangd-$COMPILER_VERSION")
+elif [[ "$COMPILER" == gcc ]]; then
+ CC="gcc-$COMPILER_VERSION"
+ CXX="g++-$COMPILER_VERSION"
+ AR="gcc-ar-$COMPILER_VERSION"
+
+ if ! apt-get -y install --dry-run "gcc-$COMPILER_VERSION" >/dev/null; then
+ # Latest gcc stack deb packages provided by
+ # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test
+ sudo add-apt-repository -y --no-update ppa:ubuntu-toolchain-r/test
+ fi
+
+ PACKAGES+=("gcc-$COMPILER_VERSION" "gcc-$COMPILER_VERSION-multilib")
+else
+ fatal "Unknown compiler: $COMPILER"
+fi
+
+# PPA with some newer build dependencies (like zstd)
+sudo add-apt-repository -y --no-update ppa:upstream-systemd-ci/systemd-ci
+sudo add-apt-repository -y --no-update --enable-source
+sudo apt-get -y update
+sudo apt-get -y build-dep systemd
+sudo apt-get -y install "${PACKAGES[@]}"
+# Install more or less recent meson and ninja with pip, since the distro versions don't
+# always support all the features we need (like --optimization=). Since the build-dep
+# command above installs the distro versions, let's install the pip ones just
+# locally and add the local bin directory to the $PATH.
+pip3 install --user -r .github/workflows/requirements.txt --require-hashes
+export PATH="$HOME/.local/bin:$PATH"
+
+$CC --version
+meson --version
+ninja --version
+
+for args in "${ARGS[@]}"; do
+ SECONDS=0
+
+ info "Checking build with $args"
+ # shellcheck disable=SC2086
+ if ! AR="$AR" \
+ CC="$CC" CC_LD="$LINKER" CFLAGS="-Werror" \
+ CXX="$CXX" CXX_LD="$LINKER" CXXFLAGS="-Werror" \
+ meson setup \
+ -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true --werror \
+ -Dnobody-group=nogroup -Dcryptolib="${CRYPTOLIB:?}" -Ddebug=false \
+ $args build; then
+
+ cat build/meson-logs/meson-log.txt
+ fatal "meson failed with $args"
+ fi
+
+ if ! meson compile -C build -v; then
+ fatal "'meson compile' failed with '$args'"
+ fi
+
+ for loader in build/src/boot/efi/*{.efi,.efi.stub}; do
+ if [[ "$(sbverify --list "$loader" 2>&1)" != "No signature table present" ]]; then
+ fatal "$loader: Gaps found in section table"
+ fi
+ done
+
+ git clean -dxf
+
+ success "Build with '$args' passed in $SECONDS seconds"
+done
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
new file mode 100644
index 0000000..f91ac03
--- /dev/null
+++ b/.github/workflows/build_test.yml
@@ -0,0 +1,38 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: Build test
+on:
+ pull_request:
+ paths:
+ - '**/meson.build'
+ - '.github/workflows/**'
+ - 'meson_options.txt'
+ - 'src/**'
+ - 'test/fuzz/**'
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-22.04
+ concurrency:
+ group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ env:
+ - { COMPILER: "gcc", COMPILER_VERSION: "11", LINKER: "bfd", CRYPTOLIB: "gcrypt" }
+ - { COMPILER: "gcc", COMPILER_VERSION: "13", LINKER: "mold", CRYPTOLIB: "openssl" }
+ - { COMPILER: "clang", COMPILER_VERSION: "14", LINKER: "mold", CRYPTOLIB: "gcrypt" }
+ - { COMPILER: "clang", COMPILER_VERSION: "15", LINKER: "bfd", CRYPTOLIB: "openssl" }
+ - { COMPILER: "clang", COMPILER_VERSION: "17", LINKER: "lld", CRYPTOLIB: "auto" }
+ env: ${{ matrix.env }}
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ - name: Build check
+ run: .github/workflows/build_test.sh
diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml
new file mode 100644
index 0000000..707ea0b
--- /dev/null
+++ b/.github/workflows/cflite_pr.yml
@@ -0,0 +1,39 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: ClusterFuzzLite PR fuzzing
+on:
+ pull_request:
+ branches:
+ - main
+ - v[0-9]+-stable
+
+permissions: read-all
+
+jobs:
+ PR:
+ runs-on: ubuntu-latest
+ if: github.repository != 'systemd/systemd' || github.event.pull_request.user.login == 'dependabot[bot]'
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ sanitizer: [address, undefined, memory]
+ steps:
+ - name: Build Fuzzers
+ id: build
+ uses: google/clusterfuzzlite/actions/build_fuzzers@v1
+ with:
+ sanitizer: ${{ matrix.sanitizer }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Run Fuzzers
+ id: run
+ uses: google/clusterfuzzlite/actions/run_fuzzers@v1
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ fuzz-seconds: 1200
+ mode: 'code-change'
+ sanitizer: ${{ matrix.sanitizer }}
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
new file mode 100644
index 0000000..66714c2
--- /dev/null
+++ b/.github/workflows/cifuzz.yml
@@ -0,0 +1,74 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# See: https://google.github.io/oss-fuzz/getting-started/continuous-integration/
+
+name: CIFuzz
+
+permissions:
+ contents: read
+
+on:
+ pull_request:
+ paths:
+ - '**/meson.build'
+ - '.github/workflows/**'
+ - 'meson_options.txt'
+ - 'src/**'
+ - 'test/fuzz/**'
+ - 'tools/oss-fuzz.sh'
+ push:
+ branches:
+ - main
+jobs:
+ Fuzzing:
+ runs-on: ubuntu-latest
+ if: github.repository == 'systemd/systemd'
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ matrix.architecture }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ sanitizer: [address, undefined, memory]
+ architecture: [x86_64]
+ include:
+ - sanitizer: address
+ architecture: i386
+ permissions:
+ security-events: write
+
+ steps:
+ - name: Build Fuzzers
+ id: build
+ uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'systemd'
+ dry-run: false
+ allowed-broken-targets-percentage: 0
+ # keep-unaffected-fuzz-targets should be removed once https://github.com/google/oss-fuzz/issues/7011 is fixed
+ keep-unaffected-fuzz-targets: true
+ sanitizer: ${{ matrix.sanitizer }}
+ architecture: ${{ matrix.architecture }}
+ output-sarif: true
+ - name: Run Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'systemd'
+ fuzz-seconds: 600
+ dry-run: false
+ sanitizer: ${{ matrix.sanitizer }}
+ output-sarif: true
+ - name: Upload Crash
+ uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
+ if: failure() && steps.build.outcome == 'success'
+ with:
+ name: ${{ matrix.sanitizer }}-${{ matrix.architecture }}-artifacts
+ path: ./out/artifacts
+ - name: Upload Sarif
+ if: always() && steps.build.outcome == 'success'
+ uses: github/codeql-action/upload-sarif@407ffafae6a767df3e0230c3df91b6443ae8df75
+ with:
+ # Path to SARIF file relative to the root of the repository
+ sarif_file: cifuzz-sarif/results.sarif
+ checkout_path: cifuzz-sarif
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..2c02ef5
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,59 @@
+---
+# 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-22.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@b4ffde65f46336ab88eb53be808477a3936bae11
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75
+ with:
+ languages: ${{ matrix.language }}
+ config-file: ./.github/codeql-config.yml
+
+ - run: sudo -E .github/workflows/unit_tests.sh SETUP
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@407ffafae6a767df3e0230c3df91b6443ae8df75
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75
diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
new file mode 100644
index 0000000..1545d59
--- /dev/null
+++ b/.github/workflows/coverity.yml
@@ -0,0 +1,30 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: Coverity
+
+on:
+ schedule:
+ # Run Coverity daily at midnight
+ - cron: '0 0 * * *'
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-22.04
+ if: github.repository == 'systemd/systemd'
+ env:
+ # Set in repo settings -> secrets -> actions
+ COVERITY_SCAN_TOKEN: "${{ secrets.COVERITY_SCAN_TOKEN }}"
+ COVERITY_SCAN_NOTIFICATION_EMAIL: "${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}"
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ # Reuse the setup phase of the unit test script to avoid code duplication
+ - name: Install build dependencies
+ run: sudo -E .github/workflows/unit_tests.sh SETUP
+ - name: Build & upload the results
+ run: tools/coverity.sh
diff --git a/.github/workflows/development_freeze.yml b/.github/workflows/development_freeze.yml
new file mode 100644
index 0000000..e371e19
--- /dev/null
+++ b/.github/workflows/development_freeze.yml
@@ -0,0 +1,74 @@
+# doc: https://github.com/redhat-plumbers-in-action/devel-freezer#readme
+---
+
+name: Development Freeze
+on:
+ workflow_run:
+ workflows: [ Gather Pull Request Metadata ]
+ types:
+ - completed
+
+env:
+ PULL_REQUEST_METADATA_DIR: pull_request
+ PULL_REQUEST_METADATA_FILE: metadata
+
+permissions:
+ contents: read
+
+jobs:
+ freezer:
+ if: >
+ github.event.workflow_run.event == 'pull_request' &&
+ github.event.workflow_run.conclusion == 'success' &&
+ github.repository == 'systemd/systemd'
+ runs-on: ubuntu-22.04
+
+ permissions:
+ pull-requests: write
+
+ steps:
+ - name: Download Pull Request Metadata artifact
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+ with:
+ script: |
+ const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ run_id: ${{ github.event.workflow_run.id }},
+ });
+
+ const matchArtifact = artifacts.data.artifacts.filter((artifact) => {
+ return artifact.name == "${{ env.PULL_REQUEST_METADATA_FILE }}"
+ })[0];
+
+ const download = await github.rest.actions.downloadArtifact({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ artifact_id: matchArtifact.id,
+ archive_format: 'zip',
+ });
+
+ const fs = require('fs');
+ fs.writeFileSync('${{ github.workspace }}/${{ env.PULL_REQUEST_METADATA_FILE }}.zip', Buffer.from(download.data));
+
+ - run: unzip ${{ env.PULL_REQUEST_METADATA_FILE }}.zip
+
+ - name: 'Get Pull Request number'
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const fs = require('fs');
+ const pr_number = Number(fs.readFileSync('./${{ env.PULL_REQUEST_METADATA_FILE }}'));
+ core.exportVariable('pr_number', pr_number);
+
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ with:
+ fetch-depth: 0
+
+ - name: Development Freezer
+ uses: redhat-plumbers-in-action/devel-freezer@67aec4a153bd9fca5322e1c4dd4d7c419fb36362
+ with:
+ pr-number: ${{ env.pr_number }}
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml
new file mode 100644
index 0000000..b04aabb
--- /dev/null
+++ b/.github/workflows/differential-shellcheck.yml
@@ -0,0 +1,35 @@
+---
+# https://github.com/redhat-plumbers-in-action/differential-shellcheck#readme
+
+name: Differential ShellCheck
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+permissions:
+ contents: read
+
+jobs:
+ lint:
+ if: github.event.repository.name != 'systemd-security'
+ runs-on: ubuntu-latest
+
+ permissions:
+ security-events: write
+
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ with:
+ fetch-depth: 0
+
+ - name: Differential ShellCheck
+ uses: redhat-plumbers-in-action/differential-shellcheck@91e2582e40236f831458392d905578d680baa138
+ with:
+ # exclude all `.in` files because they may contain unsupported syntax, and they have to be preprocessed first
+ exclude-path: '**/*.in'
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/gather-pr-metadata.yml b/.github/workflows/gather-pr-metadata.yml
new file mode 100644
index 0000000..5b3c360
--- /dev/null
+++ b/.github/workflows/gather-pr-metadata.yml
@@ -0,0 +1,37 @@
+---
+
+name: Gather Pull Request Metadata
+
+on:
+ pull_request:
+ branches: [ main ]
+
+env:
+ PULL_REQUEST_METADATA_DIR: pull_request
+ PULL_REQUEST_METADATA_FILE: metadata
+
+permissions:
+ contents: read
+
+jobs:
+ gather-metadata:
+ if: github.repository == 'systemd/systemd'
+ runs-on: ubuntu-22.04
+
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ with:
+ fetch-depth: 0
+
+ - name: Store PR number in file
+ run: |
+ mkdir -p ./${{ env.PULL_REQUEST_METADATA_DIR }}
+ echo ${{ github.event.number }} >./${{ env.PULL_REQUEST_METADATA_DIR }}/${{ env.PULL_REQUEST_METADATA_FILE }}
+
+ - name: Upload Pull Request Metadata artifact
+ uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce
+ with:
+ name: ${{ env.PULL_REQUEST_METADATA_FILE }}
+ path: ${{ env.PULL_REQUEST_METADATA_DIR }}
+ retention-days: 1
diff --git a/.github/workflows/issue_labeler.yml b/.github/workflows/issue_labeler.yml
new file mode 100644
index 0000000..d8ba0a5
--- /dev/null
+++ b/.github/workflows/issue_labeler.yml
@@ -0,0 +1,36 @@
+---
+
+name: Issue labeler
+on:
+ issues:
+ types: [ opened ]
+
+permissions:
+ contents: read
+
+jobs:
+ label-component:
+ runs-on: ubuntu-22.04
+
+ permissions:
+ issues: write
+
+ strategy:
+ matrix:
+ template: [ bug_report.yml, feature_request.yml ]
+
+ steps:
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+
+ - name: Parse issue form
+ uses: stefanbuck/github-issue-parser@c1a559d78bfb8dd05216dab9ffd2b91082ff5324
+ id: issue-parser
+ with:
+ template-path: .github/ISSUE_TEMPLATE/${{ matrix.template }}
+
+ - name: Set labels based on component field
+ uses: redhat-plumbers-in-action/advanced-issue-labeler@71bcf99aef4b9ea844db9a43755e8ac02c8e661e
+ with:
+ issue-form: ${{ steps.issue-parser.outputs.jsonString }}
+ template: ${{ matrix.template }}
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
new file mode 100644
index 0000000..7f66a53
--- /dev/null
+++ b/.github/workflows/labeler.yml
@@ -0,0 +1,119 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: "Pull Request Labeler"
+
+on:
+ pull_request_target:
+ types: [opened, synchronize, reopened, ready_for_review, closed]
+ issue_comment:
+ types: [created]
+
+permissions:
+ contents: read
+
+jobs:
+ triage:
+ if: github.repository == 'systemd/systemd'
+ runs-on: ubuntu-latest
+ permissions:
+ pull-requests: write
+
+ steps:
+ - name: Label PR based on policy in labeler.yml
+ uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594
+ if: github.event_name == 'pull_request_target' && github.event.action != 'closed'
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ configuration-path: .github/labeler.yml
+ sync-labels: "" # This is a workaround for issue 18671
+
+ - name: Set or remove labels based on systemd development workflow
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+ if: github.event_name == 'pull_request_target' && github.event.action != 'closed' && !github.event.pull_request.draft
+ with:
+ script: |
+ response = await github.rest.issues.listLabelsOnIssue({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ });
+
+ good_to_merge = [
+ "good-to-merge/waiting-for-ci 👍",
+ "good-to-merge/after-next-release",
+ "good-to-merge/with-minor-suggestions",
+ "good-to-merge/waiting-for-reporter-feedback 👍",
+ ];
+
+ if (response.data.every(l => !good_to_merge.includes(l.name))) {
+ await github.rest.issues.addLabels({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ labels: ["please-review"]
+ });
+ }
+
+ for (const label of ["reviewed/needs-rework 🔨",
+ "ci-fails/needs-rework 🔥",
+ "ci-failure-appears-unrelated",
+ "needs-rebase"]) {
+ try {
+ await github.rest.issues.removeLabel({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ name: label,
+ });
+ } catch (err) {
+ if (err.status != 404) {
+ throw err;
+ }
+ }
+ }
+
+ - name: Add please-review label on command in issue comment
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+ if: github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/please-review')
+ with:
+ script: |
+ await github.rest.issues.addLabels({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ labels: ["please-review"]
+ })
+
+ - name: Remove specific labels when PR is closed or merged
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
+ if: github.event_name == 'pull_request_target' && github.event.action == 'closed'
+ with:
+ script: |
+ for (const label of ["please-review",
+ "reviewed/needs-rework 🔨",
+ "ci-fails/needs-rework 🔥",
+ "needs-rebase",
+ "good-to-merge/waiting-for-ci 👍",
+ "good-to-merge/after-next-release",
+ "good-to-merge/with-minor-suggestions",
+ "good-to-merge/waiting-for-reporter-feedback 👍",
+ "needs-discussion 🤔",
+ "needs-reporter-feedback ❓",
+ "dont-merge 💣",
+ "squash-on-merge",
+ "quick-review 🏃‍♂️"]) {
+ try {
+ await github.rest.issues.removeLabel({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ name: label,
+ });
+ } catch (err) {
+ if (err.status != 404) {
+ throw err;
+ }
+ }
+ }
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
new file mode 100644
index 0000000..fd1a7a4
--- /dev/null
+++ b/.github/workflows/linter.yml
@@ -0,0 +1,36 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# https://github.com/marketplace/actions/super-linter
+name: Lint Code Base
+
+on:
+ pull_request:
+ branches:
+ - main
+ - v[0-9]+-stable
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: Lint Code Base
+ runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+ steps:
+ - name: Repo checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ with:
+ # We need a full repo clone
+ fetch-depth: 0
+
+ - name: Lint Code Base
+ uses: github/super-linter/slim@45fc0d88288beee4701c62761281edfee85655d7
+ env:
+ DEFAULT_BRANCH: main
+ VALIDATE_ALL_CODEBASE: false
+ VALIDATE_GITHUB_ACTIONS: true
diff --git a/.github/workflows/make_release.yml b/.github/workflows/make_release.yml
new file mode 100644
index 0000000..9902a6c
--- /dev/null
+++ b/.github/workflows/make_release.yml
@@ -0,0 +1,24 @@
+name: Make a Github release
+
+on:
+ push:
+ tags:
+ - "v*"
+
+permissions:
+ contents: read
+
+jobs:
+ release:
+ if: github.repository == 'systemd/systemd' || github.repository == 'systemd/systemd-stable'
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: write
+
+ steps:
+ - name: Release
+ uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844
+ with:
+ prerelease: ${{ contains(github.ref_name, '-rc') }}
+ draft: ${{ github.repository == 'systemd/systemd' }}
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
new file mode 100644
index 0000000..8b32ec8
--- /dev/null
+++ b/.github/workflows/mkosi.yml
@@ -0,0 +1,143 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Simple boot tests that build and boot the mkosi images generated by the mkosi config files in mkosi.conf.d/.
+name: mkosi
+
+on:
+ push:
+ branches:
+ - main
+ - v[0-9]+-stable
+ paths:
+ - '**'
+ - '!README*'
+ - '!LICENSE*'
+ - '!LICENSES/**'
+ - '!TODO'
+ - '!docs/**'
+ - '!man/**'
+ - '!catalog/**'
+ - '!shell-completion/**'
+ - '!po/**'
+ - '!.**'
+ - '.github/**'
+
+ pull_request:
+ branches:
+ - main
+ - v[0-9]+-stable
+ paths:
+ - '**'
+ - '!README*'
+ - '!LICENSE*'
+ - '!LICENSES/**'
+ - '!TODO'
+ - '!docs/**'
+ - '!man/**'
+ - '!catalog/**'
+ - '!shell-completion/**'
+ - '!po/**'
+ - '!.**'
+ - '.github/**'
+
+permissions:
+ contents: read
+
+jobs:
+ ci:
+ runs-on: ubuntu-22.04
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.distro }}-${{ matrix.release }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - distro: arch
+ release: rolling
+ - distro: debian
+ release: testing
+ - distro: ubuntu
+ release: jammy
+ - distro: fedora
+ release: "39"
+ - distro: fedora
+ release: rawhide
+ - distro: opensuse
+ release: tumbleweed
+ - distro: centos
+ release: "9"
+ - distro: centos
+ release: "8"
+
+ env:
+ SYSTEMD_LOG_LEVEL: debug
+
+ steps:
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ - uses: systemd/mkosi@bbe715f42911f9660712377a5b39335b9391ae22
+
+ - name: Configure
+ run: |
+ tee mkosi.local.conf <<- EOF
+ [Distribution]
+ Distribution=${{ matrix.distro }}
+ Release=${{ matrix.release }}
+ EOF
+
+ tee mkosi.conf.d/99-ci.conf <<- EOF
+ [Content]
+ Environment=CI_BUILD=1
+ SLOW_TESTS=true
+
+ [Host]
+ KernelCommandLineExtra=systemd.unit=mkosi-check-and-shutdown.service
+ systemd.journald.max_level_console=debug
+ # udev's debug log output is very verbose, so up it to info in CI.
+ udev.log_level=info
+ # Root device can take a long time to appear, so let's bump the timeout.
+ systemd.default_device_timeout_sec=180
+ QemuVsock=yes
+ # Sometimes we run on a host with /dev/kvm, but it is broken, so explicitly disable it
+ QemuKvm=no
+ Ephemeral=yes
+ EOF
+
+ # For erofs, we have to install linux-modules-extra-azure, but that doesn't match the running kernel
+ # version, so we can't load the erofs module. squashfs is a builtin module so we use that instead.
+
+ mkdir -p mkosi.images/system/mkosi.repart/10-usr.conf.d
+ tee mkosi.images/system/mkosi.repart/10-usr.conf.d/squashfs.conf <<- EOF
+ [Partition]
+ Format=squashfs
+ EOF
+
+ # The emergency shell is not useful in the CI, as it just blocks for a long time before the job
+ # eventually times out. Override it to just shutdown immediately.
+ mkdir -p mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/
+ mkdir -p mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/
+ tee mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf <<- EOF
+ [Unit]
+ FailureAction=exit
+ [Service]
+ ExecStartPre=
+ ExecStart=
+ ExecStart=false
+ EOF
+ cp mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf
+
+ - name: Generate secure boot key
+ run: mkosi --debug genkey
+
+ - name: Show image summary
+ run: mkosi summary
+
+ - name: Build
+ run: mkosi --debug
+
+ - name: Boot systemd-nspawn
+ run: test "$(sudo mkosi --debug boot 1>&2; echo $?)" -eq 123
+
+ - name: Boot QEMU
+ run: timeout -k 30 10m test "$(mkosi --debug qemu 1>&2; echo $?)" -eq 123
diff --git a/.github/workflows/requirements.txt b/.github/workflows/requirements.txt
new file mode 100644
index 0000000..b42b98e
--- /dev/null
+++ b/.github/workflows/requirements.txt
@@ -0,0 +1,19 @@
+meson==1.3.0 \
+ --hash=sha256:4ba253ef60e454e23234696119cbafa082a0aead0bd3bbf6991295054795f5dc \
+ --hash=sha256:e9f54046ce5b9a1f3024f7a7d52f19f085fd57c9d26a5db0cfcf0750572a8fd8
+ninja==1.11.1.1 \
+ --hash=sha256:18302d96a5467ea98b68e1cae1ae4b4fb2b2a56a82b955193c637557c7273dbd \
+ --hash=sha256:185e0641bde601e53841525c4196278e9aaf4463758da6dd1e752c0a0f54136a \
+ --hash=sha256:376889c76d87b95b5719fdd61dd7db193aa7fd4432e5d52d2e44e4c497bdbbee \
+ --hash=sha256:3e0f9be5bb20d74d58c66cc1c414c3e6aeb45c35b0d0e41e8d739c2c0d57784f \
+ --hash=sha256:73b93c14046447c7c5cc892433d4fae65d6364bec6685411cb97a8bcf815f93a \
+ --hash=sha256:7563ce1d9fe6ed5af0b8dd9ab4a214bf4ff1f2f6fd6dc29f480981f0f8b8b249 \
+ --hash=sha256:76482ba746a2618eecf89d5253c0d1e4f1da1270d41e9f54dfbd91831b0f6885 \
+ --hash=sha256:84502ec98f02a037a169c4b0d5d86075eaf6afc55e1879003d6cab51ced2ea4b \
+ --hash=sha256:95da904130bfa02ea74ff9c0116b4ad266174fafb1c707aa50212bc7859aebf1 \
+ --hash=sha256:9d793b08dd857e38d0b6ffe9e6b7145d7c485a42dcfea04905ca0cdb6017cc3c \
+ --hash=sha256:9df724344202b83018abb45cb1efc22efd337a1496514e7e6b3b59655be85205 \
+ --hash=sha256:aad34a70ef15b12519946c5633344bc775a7656d789d9ed5fdb0d456383716ef \
+ --hash=sha256:d491fc8d89cdcb416107c349ad1e3a735d4c4af5e1cb8f5f727baca6350fdaea \
+ --hash=sha256:ecf80cf5afd09f14dcceff28cb3f11dc90fb97c999c89307aea435889cb66877 \
+ --hash=sha256:fa2ba9d74acfdfbfbcf06fad1b8282de8a7a8c481d9dee45c859a8c93fcc1082
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
new file mode 100644
index 0000000..e2a9f27
--- /dev/null
+++ b/.github/workflows/scorecards.yml
@@ -0,0 +1,41 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+name: Scorecards supply-chain security
+on:
+ # Only the default branch is supported.
+ branch_protection_rule:
+ schedule:
+ - cron: '15 21 * * 6'
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+ paths:
+ - '.github/workflows/scorecards.yml'
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecards analysis
+ if: github.repository == 'systemd/systemd'
+ runs-on: ubuntu-latest
+ permissions:
+ id-token: write # Used to receive a badge.
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ with:
+ persist-credentials: false
+
+ - name: Run analysis
+ uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ publish_results: ${{ github.event_name != 'pull_request' }}
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
new file mode 100755
index 0000000..c1a5ede
--- /dev/null
+++ b/.github/workflows/unit_tests.sh
@@ -0,0 +1,123 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+# shellcheck disable=SC2206
+PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP})
+ADDITIONAL_DEPS=(
+ clang
+ expect
+ fdisk
+ jekyll
+ libbpf-dev
+ libfdisk-dev
+ libfido2-dev
+ libp11-kit-dev
+ libpwquality-dev
+ libqrencode-dev
+ libssl-dev
+ libtss2-dev
+ libxkbcommon-dev
+ libzstd-dev
+ python3-libevdev
+ python3-pefile
+ python3-pyelftools
+ python3-pyparsing
+ python3-pytest
+ rpm
+ zstd
+)
+
+function info() {
+ echo -e "\033[33;1m$1\033[0m"
+}
+
+function run_meson() {
+ if ! meson "$@"; then
+ find . -type f -name meson-log.txt -exec cat '{}' +
+ return 1
+ fi
+}
+
+set -ex
+
+MESON_ARGS=(-Dcryptolib=${CRYPTOLIB:-auto})
+
+for phase in "${PHASES[@]}"; do
+ case $phase in
+ SETUP)
+ info "Setup phase"
+ # PPA with some newer build dependencies
+ add-apt-repository -y --no-update ppa:upstream-systemd-ci/systemd-ci
+ add-apt-repository -y --no-update --enable-source
+ apt-get -y update
+ apt-get -y build-dep systemd
+ apt-get -y install "${ADDITIONAL_DEPS[@]}"
+ pip3 install -r .github/workflows/requirements.txt --require-hashes
+ ;;
+ RUN|RUN_GCC|RUN_CLANG|RUN_CLANG_RELEASE)
+ if [[ "$phase" =~ ^RUN_CLANG ]]; then
+ export CC=clang
+ export CXX=clang++
+ if [[ "$phase" == RUN_CLANG ]]; then
+ # The docs build is slow and is not affected by compiler/flags, so do it just once
+ MESON_ARGS+=(-Dman=enabled)
+ else
+ MESON_ARGS+=(-Dmode=release --optimization=2)
+ fi
+
+ # Some variation: remove machine-id, like on Debian builders to ensure unit tests still work.
+ if [ -w /etc/machine-id ]; then
+ mv /etc/machine-id /etc/machine-id.bak
+ fi
+ fi
+ MESON_ARGS+=(--fatal-meson-warnings)
+ run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true "${MESON_ARGS[@]}" build
+ ninja -C build -v
+ # Ensure setting a timezone (like the reproducible build tests do) does not break time/date unit tests
+ TZ=GMT+12 meson test -C build --print-errorlogs
+ ;;
+ RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN_NO_DEPS)
+ MESON_ARGS=(--optimization=1)
+
+ if [[ "$phase" =~ ^RUN_CLANG_ASAN_UBSAN ]]; then
+ export CC=clang
+ export CXX=clang++
+ # Build fuzzer regression tests only with clang (for now),
+ # see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604
+ # -Db_lundef=false: See https://github.com/mesonbuild/meson/issues/764
+ MESON_ARGS+=(-Db_lundef=false -Dfuzz-tests=true)
+
+ if [[ "$phase" == "RUN_CLANG_ASAN_UBSAN_NO_DEPS" ]]; then
+ MESON_ARGS+=(--auto-features=disabled)
+ fi
+ fi
+ MESON_ARGS+=(--fatal-meson-warnings)
+ run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Db_sanitize=address,undefined "${MESON_ARGS[@]}" build
+ ninja -C build -v
+
+ export ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
+ # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
+ export UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1
+
+ # FIXME
+ # For some strange reason the GH Actions VM stops responding after
+ # executing first ~150 tests, _unless_ there's something producing
+ # output (either running `meson test` in verbose mode, or something
+ # else in background). Despite my efforts so far I haven't been able
+ # to identify the culprit (since the issue is not reproducible
+ # during debugging, wonderful), so let's at least keep a workaround
+ # here to make the builds stable for the time being.
+ (set +x; while :; do echo -ne "\n[WATCHDOG] $(date)\n"; sleep 30; done) &
+ meson test --timeout-multiplier=3 -C build --print-errorlogs
+ ;;
+ CLEANUP)
+ info "Cleanup phase"
+ if [ ! -f /etc/machine-id ] && [ -w /etc/machine-id.bak ]; then
+ mv /etc/machine-id.bak /etc/machine-id
+ fi
+ ;;
+ *)
+ echo >&2 "Unknown phase '$phase'"
+ exit 1
+ esac
+done
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
new file mode 100644
index 0000000..d2164cc
--- /dev/null
+++ b/.github/workflows/unit_tests.yml
@@ -0,0 +1,45 @@
+---
+# vi: ts=2 sw=2 et:
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+name: Unit tests
+on:
+ pull_request:
+ branches:
+ - main
+ - v[0-9]+-stable
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ubuntu-22.04
+ concurrency:
+ group: ${{ github.workflow }}-${{ matrix.run_phase }}-${{ matrix.cryptolib }}-${{ github.ref }}
+ cancel-in-progress: true
+ strategy:
+ fail-fast: false
+ matrix:
+ run_phase: [GCC, GCC_ASAN_UBSAN, CLANG, CLANG_RELEASE, CLANG_ASAN_UBSAN, CLANG_ASAN_UBSAN_NO_DEPS]
+ cryptolib: [auto]
+ include:
+ - run_phase: GCC
+ cryptolib: openssl
+ - run_phase: CLANG
+ cryptolib: gcrypt
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ - name: Install build dependencies
+ run: |
+ # Drop XDG_* stuff from /etc/environment, so we don't get the user
+ # XDG_* variables when running under sudo
+ sudo sed -i '/^XDG_/d' /etc/environment
+ # Pass only specific env variables through sudo, to avoid having
+ # the already existing XDG_* stuff on the "other side"
+ sudo --preserve-env=CRYPTOLIB,GITHUB_ACTIONS,CI .github/workflows/unit_tests.sh SETUP
+ - name: Build & test
+ run: sudo --preserve-env=CRYPTOLIB,GITHUB_ACTIONS,CI .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }}
+ env:
+ CRYPTOLIB: ${{ matrix.cryptolib }}