diff options
Diffstat (limited to '.github')
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 }} |