From e844d4e24f8e63d93410a58bc1e3b0ca6dd3e2e0 Mon Sep 17 00:00:00 2001 From: Zhao Hang Date: Tue, 26 Dec 2023 10:07:06 +0800 Subject: [PATCH 01/11] update to systemd-239-78.src.rpm Signed-off-by: Zhao Hang --- ...always-create-state-file-in-signal-h.patch | 4 +- ...r-move-relinquish-code-into-function.patch | 4 +- ...always-touch-state-file-in-signal-ha.patch | 4 +- ...test-make-TEST-35-LOGIN-stable-again.patch | 299 ++++++++++ ...LESSSECURE-whenver-we-invoke-a-pager.patch | 4 +- ...s-test-sd_pid_get_owner_uid-moderniz.patch | 4 +- ...-secure-when-under-euid-is-changed-o.patch | 4 +- ...erential-shellcheck-workflow-on-push.patch | 49 ++ 0910-ci-codeql-master-main.patch | 34 ++ ...OMEDIUM-error-from-sd_pid_get_cgroup.patch | 4 +- ...op-requirements-on-linting-workflows.patch | 42 ++ ...gathering-metadata-for-source-git-au.patch | 4 +- ...-the-source-git-automation-commit-li.patch | 4 +- ...-and-forward-dummy-arguments-instead.patch | 4 +- ...S-devices-from-initramfs-in-QEMU-tes.patch | 45 ++ ...y-set-the-base-when-converting-recor.patch | 37 ++ ...ning-the-dmesg.txt-file-if-not-reque.patch | 68 +++ ...a-couple-of-tests-for-systemd-pstore.patch | 341 +++++++++++ ...sions-for-source-git-automation-work.patch | 29 + ...rol-lost-of-the-current-terminal-whe.patch | 130 +++++ ...arse_permille-check-negative-earlier.patch | 49 ++ ...se-granularity-of-percent-specificat.patch | 165 ++++++ ...no-util-introduce-ERRNO_IS_TRANSIENT.patch | 31 + 0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch | 545 ++++++++++++++++++ ...systemd-ignore-both-EINTR-and-EAGAIN.patch | 75 +++ ...us-handle-EINTR-return-from-bus_poll.patch | 90 +++ ...-bridge-don-t-be-bothered-with-EINTR.patch | 28 + ...e-EINTR-from-poll-gracefully-as-succ.patch | 36 ++ ...EINTR-returned-from-fd_wait_for_even.patch | 79 +++ ...-wtmp-fix-error-in-case-isatty-fails.patch | 28 + ...-EINTR-gracefully-when-waiting-to-wr.patch | 52 ++ ...cuum-count-size-of-all-journal-files.patch | 90 +++ ...-of-closing-DNS-UDP-transaction-fds-.patch | 365 ++++++++++++ ...DP-socket-when-we-received-a-network.patch | 26 + ...ly-labels-to-mark-downstream-only-co.patch | 24 + ...k-markup-in-systemd-pstore.service-8.patch | 39 ++ ...-.service-suffix-to-systemd-pstore-8.patch | 61 ++ ...le-systemd-pstore.service-by-default.patch | 26 + 0940-logind-simplify-code.patch | 54 ++ ...dd-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch | 89 +++ 0942-loginctl-shorten-variable-name.patch | 39 ++ ...-loginctl-use-bus_map_all_properties.patch | 137 +++++ ...session-idle-status-in-list-sessions.patch | 80 +++ ...sessions-fix-timestamp-for-idle-hint.patch | 53 ++ ...lso-show-idle-hint-in-session-status.patch | 40 ++ ...s-use-inactive_exit_timestamp-if-it-.patch | 46 ++ ...l_timestamp_is_set-in-one-more-place.patch | 25 + ...stable-from-advanced-commit-linter-c.patch | 28 + ...cape-invalid-UTF8-char-in-dbus-reply.patch | 108 ++++ ...ing-error-check-for-session_set_lead.patch | 4 +- ...sion-leader-if-we-know-for-a-fact-th.patch | 8 +- ...consistency-checks-when-logind-is-no.patch | 170 ++++++ ...t-remove-dead-code-and-use-_cleanup_.patch | 91 +++ ...estroy-inotify-data-structures-from-.patch | 100 ++++ ...ent-add-sd_event_add_inotify_fd-call.patch | 232 ++++++++ ...ase-for-self-destroy-inotify-handler.patch | 65 +++ ...add-downstream-CONTRIBUTING-document.patch | 86 +++ ...c-use-link-with-prefilled-Jira-issue.patch | 25 + ...nk-downstream-CONTRIBUTING-in-README.patch | 52 ++ ...-ordering-of-special-type.d-drop-ins.patch | 47 ++ ...-to-show-service.d-global-drop-in-do.patch | 57 ++ 0963-test-set-indentation-to-4-spaces.patch | 522 +++++++++++++++++ ...EST-15-remove-all-created-unit-files.patch | 31 + 0965-test-use-quotes-where-necessary.patch | 95 +++ ...anually-crafted-message-for-missing-.patch | 43 ++ ...-boolean-expression-in-unit_is_prist.patch | 41 ++ ...low-transient-units-to-have-drop-ins.patch | 88 +++ ...lper-functions-to-accept-other-unit-.patch | 135 +++++ ...est-hierarchical-drop-ins-for-slices.patch | 79 +++ ...st-for-transient-units-with-drop-ins.patch | 109 ++++ ...one-more-test-for-drop-in-precedence.patch | 66 +++ ...introduce-naming-scheme-for-RHEL-8.9.patch | 50 ++ ...-remove-libdw-dependency-from-pstore.patch | 27 + ...oduce-tmpfiles.d-systemd-pstore.conf.patch | 113 ++++ ...omplain-if-we-can-t-enable-pstore-in.patch | 25 + ...ble-crash_kexec_post_notifiers-by-de.patch | 66 +++ ...te-yes-is-set-for-a-unit-run-ExecSta.patch | 217 +++++++ ...e-documentation-up-with-the-markdown.patch | 26 + ...ull-reference-case-in-load_from_path.patch | 34 -- ...-t-pass-null-directive-argument-to-s.patch | 25 - ...roduce-EXIT_EXCEPTION-mapping-to-255.patch | 52 -- ...e-PID-1-in-containers-exit-with-non-.patch | 52 -- ...t-go-into-freeze-when-systemd-crashd.patch | 103 ---- ...ge-the-system-mount-propagation-to-s.patch | 62 -- ...-definition-of-CGROUP_CONTROLLER_TO_.patch | 26 - ...only-siblings-that-got-realized-once.patch | 46 -- ...g-item-to-support-setting-the-value-.patch | 120 ---- ...9-systemd-anolis-support-loongarch64.patch | 56 -- ...x-coredump-when-compiled-under-GCC10.patch | 56 -- 10011-hwdb-add-Iluvatar-CoreX.patch | 44 -- 10012-seccomp-add-loongarch-support.patch | 101 ---- ...ding-a-full-file-into-memory-refuse-.patch | 120 ---- ...explicit_bzero_safe-for-explicit-mem.patch | 61 -- ...util-introduce-erase_and_free-helper.patch | 48 -- ...READ_FULL_FILE_SECURE-flag-for-readi.patch | 207 ------- ...roduce-warn_file_is_world_accessible.patch | 67 --- ...l_file_full-also-warns-when-file-is-.patch | 64 -- ...x-memory-leak-if-READ_FULL_FILE_SECU.patch | 30 - ...icit-flag-for-generating-world-execu.patch | 44 -- ..._fd-parameter-to-read_full_file_full.patch | 142 ----- ...ort-for-read_full_file-on-AF_UNIX-st.patch | 271 --------- ...READ_FULL_FILE_CONNECT_SOCKET-to-all.patch | 181 ------ ...ad_full_file_full-to-read-from-offse.patch | 246 -------- ...-cryptsetup-s-main-key-file-logic-ov.patch | 95 --- ...FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch | 69 --- 20001-hwdb-parse_hwdb_dot_py.patch | 299 ---------- ...fresh-cgroup-devices-config-when-dae.patch | 26 - ...group-full-delegation-for-compabilit.patch | 133 ----- README.md | 11 - dist | 2 +- systemd.spec | 273 +++++---- 111 files changed, 6438 insertions(+), 3020 deletions(-) create mode 100644 0905-test-make-TEST-35-LOGIN-stable-again.patch rename 0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch => 0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch (98%) rename 0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch => 0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch (99%) rename 0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch => 0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch (99%) create mode 100644 0909-ci-trigger-differential-shellcheck-workflow-on-push.patch create mode 100644 0910-ci-codeql-master-main.patch rename 0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch => 0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch (93%) create mode 100644 0912-ci-Mergify-drop-requirements-on-linting-workflows.patch rename 0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch => 0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch (94%) rename 0911-ci-first-part-of-the-source-git-automation-commit-li.patch => 0914-ci-first-part-of-the-source-git-automation-commit-li.patch (97%) rename 0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch => 0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch (92%) create mode 100644 0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch create mode 100644 0917-pstore-explicitly-set-the-base-when-converting-recor.patch create mode 100644 0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch create mode 100644 0919-test-add-a-couple-of-tests-for-systemd-pstore.patch create mode 100644 0920-ci-update-permissions-for-source-git-automation-work.patch create mode 100644 0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch create mode 100644 0922-parse-util-in-parse_permille-check-negative-earlier.patch create mode 100644 0923-tree-wide-increase-granularity-of-percent-specificat.patch create mode 100644 0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch create mode 100644 0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch create mode 100644 0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch create mode 100644 0927-sd-bus-handle-EINTR-return-from-bus_poll.patch create mode 100644 0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch create mode 100644 0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch create mode 100644 0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch create mode 100644 0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch create mode 100644 0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch create mode 100644 0933-journal-vacuum-count-size-of-all-journal-files.patch create mode 100644 0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch create mode 100644 0935-resolved-close-UDP-socket-when-we-received-a-network.patch create mode 100644 0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch create mode 100644 0937-man-tweak-markup-in-systemd-pstore.service-8.patch create mode 100644 0938-man-add-.service-suffix-to-systemd-pstore-8.patch create mode 100644 0939-presets-enable-systemd-pstore.service-by-default.patch create mode 100644 0940-logind-simplify-code.patch create mode 100644 0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch create mode 100644 0942-loginctl-shorten-variable-name.patch create mode 100644 0943-loginctl-use-bus_map_all_properties.patch create mode 100644 0944-loginctl-show-session-idle-status-in-list-sessions.patch create mode 100644 0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch create mode 100644 0946-loginctl-also-show-idle-hint-in-session-status.patch create mode 100644 0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch create mode 100644 0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch create mode 100644 0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch create mode 100644 0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch rename 0912-login-add-a-missing-error-check-for-session_set_lead.patch => 0951-login-add-a-missing-error-check-for-session_set_lead.patch (92%) rename 0913-logind-reset-session-leader-if-we-know-for-a-fact-th.patch => 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch (93%) create mode 100644 0953-test-login-skip-consistency-checks-when-logind-is-no.patch create mode 100644 0954-sd-event-remove-dead-code-and-use-_cleanup_.patch create mode 100644 0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch create mode 100644 0956-sd-event-add-sd_event_add_inotify_fd-call.patch create mode 100644 0957-test-add-test-case-for-self-destroy-inotify-handler.patch create mode 100644 0958-doc-add-downstream-CONTRIBUTING-document.patch create mode 100644 0959-doc-use-link-with-prefilled-Jira-issue.patch create mode 100644 0960-docs-link-downstream-CONTRIBUTING-in-README.patch create mode 100644 0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch create mode 100644 0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch create mode 100644 0963-test-set-indentation-to-4-spaces.patch create mode 100644 0964-test-TEST-15-remove-all-created-unit-files.patch create mode 100644 0965-test-use-quotes-where-necessary.patch create mode 100644 0966-tree-wide-drop-manually-crafted-message-for-missing-.patch create mode 100644 0967-manager-reformat-boolean-expression-in-unit_is_prist.patch create mode 100644 0968-manager-allow-transient-units-to-have-drop-ins.patch create mode 100644 0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch create mode 100644 0970-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch create mode 100644 0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch create mode 100644 0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch create mode 100644 0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch create mode 100644 0974-meson-remove-libdw-dependency-from-pstore.patch create mode 100644 0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch create mode 100644 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch create mode 100644 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch create mode 100644 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch create mode 100644 0979-man-link-Delegate-documentation-up-with-the-markdown.patch delete mode 100644 10000-core-fix-a-null-reference-case-in-load_from_path.patch delete mode 100644 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch delete mode 100644 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch delete mode 100644 10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch delete mode 100644 10004-Do-not-go-into-freeze-when-systemd-crashd.patch delete mode 100644 10005-mount-setup-change-the-system-mount-propagation-to-s.patch delete mode 100644 10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch delete mode 100644 10007-cgroup-update-only-siblings-that-got-realized-once.patch delete mode 100644 10008-core-add-a-config-item-to-support-setting-the-value-.patch delete mode 100644 10009-systemd-anolis-support-loongarch64.patch delete mode 100644 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch delete mode 100644 10011-hwdb-add-Iluvatar-CoreX.patch delete mode 100644 10012-seccomp-add-loongarch-support.patch delete mode 100644 10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch delete mode 100644 10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch delete mode 100644 10015-util-introduce-erase_and_free-helper.patch delete mode 100644 10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch delete mode 100644 10017-fileio-introduce-warn_file_is_world_accessible.patch delete mode 100644 10018-fileio-read_full_file_full-also-warns-when-file-is-.patch delete mode 100644 10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch delete mode 100644 10020-fileio-add-explicit-flag-for-generating-world-execu.patch delete mode 100644 10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch delete mode 100644 10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch delete mode 100644 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch delete mode 100644 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch delete mode 100644 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch delete mode 100644 10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch delete mode 100644 20001-hwdb-parse_hwdb_dot_py.patch delete mode 100644 20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch delete mode 100644 20003-core-introduce-cgroup-full-delegation-for-compabilit.patch delete mode 100644 README.md diff --git a/0902-journald-server-always-create-state-file-in-signal-h.patch b/0902-journald-server-always-create-state-file-in-signal-h.patch index b09df96..ed9308c 100644 --- a/0902-journald-server-always-create-state-file-in-signal-h.patch +++ b/0902-journald-server-always-create-state-file-in-signal-h.patch @@ -1,4 +1,4 @@ -From 47cc8f7e1d153e576f146d309b4043739997a673 Mon Sep 17 00:00:00 2001 +From 0491902d0eff9f4480ce873decc5dd29e5e189d7 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Mon, 13 Mar 2023 14:22:28 +0100 Subject: [PATCH] journald-server: always create state file in signal handler @@ -8,7 +8,7 @@ nothing has really happened. RHEL-only -Resolves: #2174645 +Resolves: #2176892 --- src/journal/journald-server.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/0903-journald-server-move-relinquish-code-into-function.patch b/0903-journald-server-move-relinquish-code-into-function.patch index 46f057d..8536ff8 100644 --- a/0903-journald-server-move-relinquish-code-into-function.patch +++ b/0903-journald-server-move-relinquish-code-into-function.patch @@ -1,4 +1,4 @@ -From 7a7b0c4ec7a5595a44d9c70d8270b0724a8b8c45 Mon Sep 17 00:00:00 2001 +From 62c8e07498c9dd13aa79371fc169bb51652ef3a9 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Mon, 13 Mar 2023 14:31:38 +0100 Subject: [PATCH] journald-server: move relinquish code into function @@ -7,7 +7,7 @@ No functional change, just refactoring. RHEL-only -Related: #2174645 +Related: #2176892 --- src/journal/journald-server.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/0904-journald-server-always-touch-state-file-in-signal-ha.patch b/0904-journald-server-always-touch-state-file-in-signal-ha.patch index 40267b7..b6b9436 100644 --- a/0904-journald-server-always-touch-state-file-in-signal-ha.patch +++ b/0904-journald-server-always-touch-state-file-in-signal-ha.patch @@ -1,4 +1,4 @@ -From 980add7d84084a474c6c604c0670743c2d1e624c Mon Sep 17 00:00:00 2001 +From 05a06e34ac8a38c1cff2a08ba071386141e0b78d Mon Sep 17 00:00:00 2001 From: David Tardon Date: Mon, 13 Mar 2023 14:32:20 +0100 Subject: [PATCH] journald-server: always touch state file in signal handler @@ -8,7 +8,7 @@ even if nothing has really happened. RHEL-only -Related: #2174645 +Related: #2176892 --- src/journal/journald-server.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/0905-test-make-TEST-35-LOGIN-stable-again.patch b/0905-test-make-TEST-35-LOGIN-stable-again.patch new file mode 100644 index 0000000..45fa87d --- /dev/null +++ b/0905-test-make-TEST-35-LOGIN-stable-again.patch @@ -0,0 +1,299 @@ +From 96e69cb655c703d5312c4aa44912e6ce90b4f76f Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 29 Mar 2023 22:38:55 +0200 +Subject: [PATCH] test: make TEST-35-LOGIN stable again + +The expect stuff was anything but expected, so let's just backport +the upstream test case and tweak it a bit to account for the missing +parts in our downstream testing infrastructure. + +Follow-up to 638c2418e7. +Related: #2179309 +rhel-only +--- + test/TEST-35-LOGIN/testsuite.sh | 225 ++++++++++++++++++++++++-------- + test/test-functions | 2 +- + 2 files changed, 175 insertions(+), 52 deletions(-) + +diff --git a/test/TEST-35-LOGIN/testsuite.sh b/test/TEST-35-LOGIN/testsuite.sh +index e4d72beb74..149b2354a1 100755 +--- a/test/TEST-35-LOGIN/testsuite.sh ++++ b/test/TEST-35-LOGIN/testsuite.sh +@@ -3,6 +3,141 @@ + set -eux + set -o pipefail + ++cleanup_test_user() ( ++ set +ex ++ ++ pkill -u "$(id -u logind-test-user)" ++ sleep 1 ++ pkill -KILL -u "$(id -u logind-test-user)" ++ userdel -r logind-test-user ++ ++ return 0 ++) ++ ++setup_test_user() { ++ mkdir -p /var/spool/cron /var/spool/mail /var/run/console ++ useradd -m -s /bin/bash logind-test-user ++ trap cleanup_test_user EXIT ++} ++ ++test_enable_debug() { ++ mkdir -p /run/systemd/system/systemd-logind.service.d ++ cat >/run/systemd/system/systemd-logind.service.d/debug.conf <&2 ++ return 1 ++ fi ++ ++ seat=$(loginctl --no-legend | grep 'logind-test-user *seat' | awk '{ print $4 }') ++ if [[ -z "$seat" ]]; then ++ echo "no seat found for user logind-test-user" >&2 ++ return 1 ++ fi ++ ++ session=$(loginctl --no-legend | awk '$3 == "logind-test-user" { print $1 }') ++ if [[ -z "$session" ]]; then ++ echo "no session found for user logind-test-user" >&2 ++ return 1 ++ fi ++ ++ if ! loginctl session-status "$session" | grep -q "Unit: session-${session}\.scope"; then ++ echo "cannot find scope unit for session $session" >&2 ++ return 1 ++ fi ++ ++ leader_pid=$(loginctl session-status "$session" | awk '$1 == "Leader:" { print $2 }') ++ if [[ -z "$leader_pid" ]]; then ++ echo "cannot found leader process for session $session" >&2 ++ return 1 ++ fi ++ ++ # cgroup v1: "1:name=systemd:/user.slice/..."; unified hierarchy: "0::/user.slice" ++ if ! grep -q -E '(name=systemd|^0:):.*session.*scope' /proc/"$leader_pid"/cgroup; then ++ echo "FAIL: process $leader_pid is not in the session cgroup" >&2 ++ cat /proc/self/cgroup ++ return 1 ++ fi ++) ++ ++create_session() { ++ # login with the test user to start a session ++ mkdir -p /run/systemd/system/getty@tty2.service.d ++ cat >/run/systemd/system/getty@tty2.service.d/override.conf </dev/null ; then +- echo >&2 "expect not installed, skiping test ${FUNCNAME[0]}" +- return 0 +- fi ++ cleanup_session + +- setup_idle_action_lock +- trap teardown_idle_action_lock RETURN ++ return 0 ++) + +- if loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -q testuser ; then +- echo >&2 "Session of the \'testuser\' is already present." +- return 1 ++test_lock_idle_action() { ++ local ts ++ ++ if [[ ! -c /dev/tty2 ]]; then ++ echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}." ++ return + fi + +- # IdleActionSec is set 1s but the accuracy of associated timer is 30s so we +- # need to sleep in worst case for 31s to make sure timer elapsed. We sleep +- # here for 35s to accomodate for any possible scheudling delays. +- cat > /tmp/test.exp <&2 "Session of the \'logind-test-user\' is already present." ++ exit 1 ++ fi + +- ts="$(date '+%H:%M:%S')" +- busctl --match "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='Lock'" monitor > dbus.log & ++ trap teardown_lock_idle_action RETURN + +- expect /tmp/test.exp & ++ create_session + +- # Sleep a bit to give expect time to spawn systemd-run before we check for +- # the presence of resulting session. +- sleep 2 +- if [ "$(loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -c testuser)" != 1 ] ; then +- echo >&2 "\'testuser\' is expected to have exactly one session running." +- return 1 +- fi ++ ts="$(date '+%H:%M:%S')" + +- wait %2 +- sleep 20 +- kill %1 ++ mkdir -p /run/systemd/logind.conf.d ++ cat >/run/systemd/logind.conf.d/idle-action-lock.conf <&2 "Too few 'Lock' D-Bus signal sent, expected at least 2." +- return 1 +- fi ++ timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 1 ]]; do sleep 1; done" ++ ++ # Wakeup ++ touch /dev/tty2 ++ ++ # Wait again ++ timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 2 ]]; do sleep 1; done" + +- journalctl -b -u systemd-logind.service --since="$ts" > logind.log +- if [ "$(grep -c 'System idle. Doing lock operation.' logind.log)" -lt 2 ]; then ++ if [[ "$(journalctl -b -u systemd-logind.service --since="$ts" | grep -c 'System idle. Doing lock operation.')" -lt 2 ]]; then + echo >&2 "System haven't entered idle state at least 2 times." +- return 1 ++ exit 1 + fi +- +- rm -f dbus.log logind.log + } + + : >/failed + ++setup_test_user ++test_enable_debug + test_lock_idle_action + + touch /testok +diff --git a/test/test-functions b/test/test-functions +index 9606a1b085..e5d4d28a5f 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch b/0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch similarity index 98% rename from 0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch rename to 0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch index caba846..ddb15e1 100644 --- a/0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch +++ b/0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch @@ -1,4 +1,4 @@ -From e0488facf5b6e1faa292460548cfe0d7c542918d Mon Sep 17 00:00:00 2001 +From c971d99ffc43df89ca4e15cd81f9e44f4139ba91 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 31 Aug 2020 19:37:13 +0200 Subject: [PATCH] pager: set $LESSSECURE whenver we invoke a pager @@ -12,7 +12,7 @@ Prompted by #5666 (cherry picked from commit 612ebf6c913dd0e4197c44909cb3157f5c51a2f0) -Related: #2175623 +Related: #2175624 --- man/less-variables.xml | 8 ++++++++ man/systemctl.xml | 1 + diff --git a/0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch b/0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch similarity index 99% rename from 0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch rename to 0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch index b1691c3..c68d02d 100644 --- a/0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch +++ b/0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch @@ -1,4 +1,4 @@ -From cd2d72208df18c0894d2e6eea0656603e326f9cf Mon Sep 17 00:00:00 2001 +From a45636228c7000aef000e45d9853585e51bfb9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 12 Oct 2020 18:57:32 +0200 Subject: [PATCH] test-login: always test sd_pid_get_owner_uid(), modernize @@ -12,7 +12,7 @@ to return anything except 0 or error. (cherry picked from commit 1b5b507cd2d1d7a2b053151abb548475ad9c5c3b) -Related: #2175623 +Related: #2175624 --- src/libsystemd/sd-login/test-login.c | 132 ++++++++++++++------------- 1 file changed, 71 insertions(+), 61 deletions(-) diff --git a/0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch b/0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch similarity index 99% rename from 0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch rename to 0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch index 543ff64..101d8c4 100644 --- a/0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch +++ b/0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch @@ -1,4 +1,4 @@ -From 9c8a6018ed4a4da6efb1fc6958e70f9324bb5b1e Mon Sep 17 00:00:00 2001 +From 7955f053c498a70616ac6c4d57c0fd47dfa8e5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 7 Oct 2020 11:15:05 +0200 Subject: [PATCH] pager: make pager secure when under euid is changed or @@ -32,7 +32,7 @@ v3: (cherry picked from commit 0a42426d797406b4b01a0d9c13bb759c2629d108) -Resolves: #2175623 +Resolves: #2175624 --- man/less-variables.xml | 28 ++++++++++++++--- meson.build | 3 +- diff --git a/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch b/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch new file mode 100644 index 0000000..4845dee --- /dev/null +++ b/0909-ci-trigger-differential-shellcheck-workflow-on-push.patch @@ -0,0 +1,49 @@ +From c4c9126b1d64fbe77ef1a74b464646711ced8f83 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 30 Mar 2023 17:16:44 +0200 +Subject: [PATCH] ci: trigger differential-shellcheck workflow on push + +Fixes: redhat-plumbers-in-action/differential-shellcheck#215 + +rhel-only + +Related: #2179309 +--- + .github/workflows/differential-shellcheck.yml | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml +index 4399f0bc64..19634c07b3 100644 +--- a/.github/workflows/differential-shellcheck.yml ++++ b/.github/workflows/differential-shellcheck.yml +@@ -3,9 +3,13 @@ + + name: Differential ShellCheck + on: ++ push: ++ branches: ++ - main ++ - rhel-8.*.0 + pull_request: + branches: +- - master ++ - main + - rhel-8.*.0 + + permissions: +@@ -18,7 +22,6 @@ jobs: + + permissions: + security-events: write +- pull-requests: write + + steps: + - name: Repository checkout +@@ -27,6 +30,6 @@ jobs: + fetch-depth: 0 + + - name: Differential ShellCheck +- uses: redhat-plumbers-in-action/differential-shellcheck@v3 ++ uses: redhat-plumbers-in-action/differential-shellcheck@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/0910-ci-codeql-master-main.patch b/0910-ci-codeql-master-main.patch new file mode 100644 index 0000000..edd131e --- /dev/null +++ b/0910-ci-codeql-master-main.patch @@ -0,0 +1,34 @@ +From 5e5c1425db0982c9d5e5d51e164895aa780f76b2 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 30 Mar 2023 17:18:17 +0200 +Subject: [PATCH] ci: codeql `master` -> `main` + +rhel-only + +Related: #2179309 +--- + .github/workflows/codeql.yml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml +index c5426d5686..cc4fcf4754 100644 +--- a/.github/workflows/codeql.yml ++++ b/.github/workflows/codeql.yml +@@ -7,7 +7,7 @@ name: "CodeQL" + on: + pull_request: + branches: +- - master ++ - main + - rhel-* + paths: + - '**/meson.build' +@@ -17,7 +17,7 @@ on: + - 'tools/**' + push: + branches: +- - master ++ - main + - rhel-* + + permissions: diff --git a/0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch b/0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch similarity index 93% rename from 0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch rename to 0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch index 405232b..6d35361 100644 --- a/0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch +++ b/0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch @@ -1,4 +1,4 @@ -From 1d8931bb5d65e9f77b470835786a97f814bd93ea Mon Sep 17 00:00:00 2001 +From d9e2735b88513e3b3af9ab468f4d2ba0f6bec64d Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Fri, 23 Oct 2020 15:50:28 -0400 Subject: [PATCH] test: ignore ENOMEDIUM error from sd_pid_get_cgroup() @@ -10,7 +10,7 @@ building the package in a Launchpad PPA. (cherry picked from commit 352ab9d74049b4ac694fdba1a6e67339f12ded93) -Related: #2175623 +Resolves: #2175622 --- src/libsystemd/sd-login/test-login.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch b/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch new file mode 100644 index 0000000..e10ce1f --- /dev/null +++ b/0912-ci-Mergify-drop-requirements-on-linting-workflows.patch @@ -0,0 +1,42 @@ +From d0e8ca2dcc1467a9e28c569e0dc608e5426bae79 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 24 Apr 2023 15:25:02 +0200 +Subject: [PATCH] ci(Mergify): drop requirements on linting workflows + +CodeQL and DifferentialShellCheck workflows aren't run for all PRs on all branches. +This results in Mergify incorrectly labeling PRs with `needs-ci` label. +Lets drop the requirements on these workflows. + +rhel-only + +Related: #2179309 +--- + .mergify.yml | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/.mergify.yml b/.mergify.yml +index a5eed6a82a..624eb7291d 100644 +--- a/.mergify.yml ++++ b/.mergify.yml +@@ -11,10 +11,6 @@ pull_request_rules: + - -check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - -check-success=CentOS CI (CentOS Stream 8) +- # CodeQL +- - -check-success=CodeQL +- # Other +- - -check-success=Differential ShellCheck + actions: + label: + add: +@@ -30,10 +26,6 @@ pull_request_rules: + - check-success=build (stream8, GCC_ASAN) + # CentOS Stream CI + - check-success=CentOS CI (CentOS Stream 8) +- # CodeQL +- - check-success=CodeQL +- # Other +- - check-success=Differential ShellCheck + actions: + label: + remove: diff --git a/0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch b/0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch similarity index 94% rename from 0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch rename to 0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch index 3b3abf3..c1a27a7 100644 --- a/0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch +++ b/0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch @@ -1,4 +1,4 @@ -From d78272e6c2dddcbca891cb5d561f23ff766486a8 Mon Sep 17 00:00:00 2001 +From a81ace51e1efa2313fcad18f2ef5c6c6cd167240 Mon Sep 17 00:00:00 2001 From: Jan Macku Date: Mon, 24 Apr 2023 15:13:08 +0200 Subject: [PATCH] ci: workflow for gathering metadata for source-git automation @@ -9,7 +9,7 @@ This workflow also triggers for rest of the source-git automation workflows. rhel-only -Related: #2190153 +Related: #2179309 --- .github/workflows/gather-metadata.yml | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/0911-ci-first-part-of-the-source-git-automation-commit-li.patch b/0914-ci-first-part-of-the-source-git-automation-commit-li.patch similarity index 97% rename from 0911-ci-first-part-of-the-source-git-automation-commit-li.patch rename to 0914-ci-first-part-of-the-source-git-automation-commit-li.patch index e6dc994..4961ca3 100644 --- a/0911-ci-first-part-of-the-source-git-automation-commit-li.patch +++ b/0914-ci-first-part-of-the-source-git-automation-commit-li.patch @@ -1,4 +1,4 @@ -From e08bdd25344ed475f48d22a1c303421e19489427 Mon Sep 17 00:00:00 2001 +From 7e0eb456a99229d19b8e42491c1ddb7b8050903f Mon Sep 17 00:00:00 2001 From: Jan Macku Date: Mon, 24 Apr 2023 15:15:00 +0200 Subject: [PATCH] ci: first part of the source-git automation - commit linter @@ -13,7 +13,7 @@ is configured via the `advanced-commit-linter.yml` file. rhel-only -Related: #2190153 +Related: #2179309 --- .github/advanced-commit-linter.yml | 23 +++++++++++ .github/workflows/source-git-automation.yml | 45 +++++++++++++++++++++ diff --git a/0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch b/0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch similarity index 92% rename from 0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch rename to 0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch index 588c30f..d978500 100644 --- a/0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch +++ b/0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch @@ -1,4 +1,4 @@ -From 5bb3dd9c96b55a4a9da23ed96b5a2681d82dc500 Mon Sep 17 00:00:00 2001 +From f86a51500b5aa9288dbb2800e0a1f63ad863bd8f Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Wed, 26 Apr 2023 20:07:10 +0200 Subject: [PATCH] pstore: fix crash and forward dummy arguments instead of NULL @@ -11,7 +11,7 @@ instead.] rhel-only -Related: #2190153 +Related: #2190151 --- src/pstore/pstore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch b/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch new file mode 100644 index 0000000..a2df2e4 --- /dev/null +++ b/0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch @@ -0,0 +1,45 @@ +From 6fdc5f71ee28829bdedb159e7d138f7a1b447fb2 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Wed, 13 Nov 2019 10:46:08 -0800 +Subject: [PATCH] test: Disable LUKS devices from initramfs in QEMU tests + +We currently use the host's kernel and initramfs in our QEMU tests. + +If the host is running on an encrypted LUKS partition, then the initramfs +will have a crypttab setup looking for the particular root disk it needs to +encrypt before booting into the system. + +However, this disk obviously doesn't exist in our QEMU VM, so it turns out +our tests end up waiting for this device to become available, which will +never actually happen, and boot hangs for 90s until that service times out. + +[*** ] A start job is running for /dev/disk/by-uuid/01234567-abcd-1234-abcd-0123456789ab (20s / 1min 30s) + +In order to prevent this issue, let's pass "rd.luks=0" to disable LUKS in +the initramfs only as part of our default kernel command-line in our QEMU +tests. + +This is enough to disable this behavior and prevent the timeout, while at +the same time doesn't conflict with our tests that actually check for LUKS +behavior in the systemd running under test (such as TEST-02-CRYPTSETUP). + +Tested: `sudo make -C TEST-02-CRYPTSETUP/ clean setup run` +(cherry picked from commit 14e0259b499c188de09040f2e5857a0193094d5a) + +Related: #2190151 +--- + test/test-functions | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/test/test-functions b/test/test-functions +index e5d4d28a5f..a7b18991f4 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -154,6 +154,7 @@ fi + KERNEL_APPEND="$PARAMS \ + root=/dev/sda1 \ + raid=noautodetect \ ++rd.luks=0 \ + loglevel=2 \ + init=$PATH_TO_INIT \ + console=ttyS0 \ diff --git a/0917-pstore-explicitly-set-the-base-when-converting-recor.patch b/0917-pstore-explicitly-set-the-base-when-converting-recor.patch new file mode 100644 index 0000000..dd3941a --- /dev/null +++ b/0917-pstore-explicitly-set-the-base-when-converting-recor.patch @@ -0,0 +1,37 @@ +From 3aefa216bf5e8bcfaf5a628e9e06672e786ce9ea Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 28 Apr 2023 11:09:22 +0200 +Subject: [PATCH] pstore: explicitly set the base when converting record ID + +(cherry picked from commit a95d96a2430db171b40fc2e50589807236f8f746) + +Related: #2190151 +--- + src/pstore/pstore.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 5335c9f92d..073fedb7d2 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -207,7 +207,7 @@ static int append_dmesg(PStoreEntry *pe, const char *subdir1, const char *subdir + static int process_dmesg_files(PStoreList *list) { + /* Move files, reconstruct dmesg.txt */ + _cleanup_free_ char *erst_subdir = NULL; +- uint64_t last_record_id = 0; ++ unsigned long long last_record_id = 0; + + /* When dmesg is written into pstore, it is done so in small chunks, whatever the exchange buffer + * size is with the underlying pstore backend (ie. EFI may be ~2KiB), which means an example +@@ -263,9 +263,9 @@ static int process_dmesg_files(PStoreList *list) { + } else if ((p = startswith(pe->dirent.d_name, "dmesg-erst-"))) { + /* For the ERST backend, the record is a monotonically increasing number, seeded as + * a timestamp. See linux/drivers/acpi/apei/erst.c in erst_writer(). */ +- uint64_t record_id; ++ unsigned long long record_id; + +- if (safe_atou64(p, &record_id) < 0) ++ if (safe_atollu_full(p, 10, &record_id) < 0) + continue; + if (last_record_id - 1 != record_id) + /* A discontinuity in the number has been detected, this current record id diff --git a/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch b/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch new file mode 100644 index 0000000..a600799 --- /dev/null +++ b/0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch @@ -0,0 +1,68 @@ +From 7a76b2a073b5df72e9afc39dc6c0cce388e0a733 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 28 Apr 2023 11:50:33 +0200 +Subject: [PATCH] pstore: avoid opening the dmesg.txt file if not requested + +Even with Storage=journal we would still attempt to open the final +dmesg.txt file which causes a lot of noise in the journal: + +``` +[ 5.764111] H testsuite-82.sh[658]: + systemctl start systemd-pstore +[ 5.806385] H systemd[1]: Starting modprobe@efi_pstore.service... +[ 5.808656] H systemd[1]: modprobe@efi_pstore.service: Deactivated successfully. +[ 5.808971] H systemd[1]: Finished modprobe@efi_pstore.service. +[ 5.818845] H kernel: audit: type=1130 audit(1682630623.637:114): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel msg='unit=modprobe@efi_pstore comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? termin> +[ 5.818865] H kernel: audit: type=1131 audit(1682630623.637:115): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel msg='unit=modprobe@efi_pstore comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? termin> +[ 5.816052] H systemd[1]: Starting systemd-pstore.service... +[ 5.840703] H systemd-pstore[806]: PStore dmesg-efi-168263062313014. +[ 5.841239] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841428] H systemd-pstore[806]: PStore dmesg-efi-168263062312014. +[ 5.841575] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841712] H systemd-pstore[806]: PStore dmesg-efi-168263062311014. +[ 5.841839] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.841989] H systemd-pstore[806]: PStore dmesg-efi-168263062310014. +[ 5.842141] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842274] H systemd-pstore[806]: PStore dmesg-efi-168263062309014. +[ 5.842423] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842589] H systemd-pstore[806]: PStore dmesg-efi-168263062308014. +[ 5.842722] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.842865] H systemd-pstore[806]: PStore dmesg-efi-168263062307014. +[ 5.843003] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843153] H systemd-pstore[806]: PStore dmesg-efi-168263062306014. +[ 5.843280] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843434] H systemd-pstore[806]: PStore dmesg-efi-168263062305014. +[ 5.843570] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843702] H systemd-pstore[806]: PStore dmesg-efi-168263062304014. +[ 5.843831] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.843958] H systemd-pstore[806]: PStore dmesg-efi-168263062303014. +[ 5.844093] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844250] H systemd-pstore[806]: PStore dmesg-efi-168263062302014. +[ 5.844412] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844619] H systemd-pstore[806]: PStore dmesg-efi-168263062301014. +[ 5.844781] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.844956] H systemd-pstore[806]: PStore dmesg-efi-168263062300014. +[ 5.845168] H systemd-pstore[806]: Failed to open file /var/lib/systemd/pstore/1682630623/014/dmesg.txt: Operation not permitted +[ 5.851101] H systemd[1]: Finished systemd-pstore.service. +``` + +(cherry picked from commit ad5980803adac8dc1cf980447a07cb18962c238b) + +Related: #2190151 +--- + src/pstore/pstore.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 073fedb7d2..9367071833 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -181,6 +181,9 @@ static int append_dmesg(PStoreEntry *pe, const char *subdir1, const char *subdir + + assert(pe); + ++ if (arg_storage != PSTORE_STORAGE_EXTERNAL) ++ return 0; ++ + if (pe->content_size == 0) + return 0; + diff --git a/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch b/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch new file mode 100644 index 0000000..029f380 --- /dev/null +++ b/0919-test-add-a-couple-of-tests-for-systemd-pstore.patch @@ -0,0 +1,341 @@ +From 06b0704a8bb41fa9a496f5671e191dc7b6c7ed9b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 3 May 2023 15:25:18 +0200 +Subject: [PATCH] test: add a couple of tests for systemd-pstore + +Based on: + - 6858e32d730fd5574eaa3d7fbf4cb12aacaea336 + - edea0d6ac57610b7af603b833b19a846327e3638 + +Related: #2190151 +--- + test/TEST-74-AUX-UTILS/Makefile | 1 + + test/TEST-74-AUX-UTILS/test.sh | 48 +++++ + test/TEST-74-AUX-UTILS/testsuite.pstore.sh | 218 +++++++++++++++++++++ + test/TEST-74-AUX-UTILS/testsuite.sh | 14 ++ + test/test-functions | 2 +- + 5 files changed, 282 insertions(+), 1 deletion(-) + create mode 120000 test/TEST-74-AUX-UTILS/Makefile + create mode 100755 test/TEST-74-AUX-UTILS/test.sh + create mode 100755 test/TEST-74-AUX-UTILS/testsuite.pstore.sh + create mode 100755 test/TEST-74-AUX-UTILS/testsuite.sh + +diff --git a/test/TEST-74-AUX-UTILS/Makefile b/test/TEST-74-AUX-UTILS/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-74-AUX-UTILS/test.sh b/test/TEST-74-AUX-UTILS/test.sh +new file mode 100755 +index 0000000000..fead257337 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/test.sh +@@ -0,0 +1,48 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Tests for auxiliary utilities" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service <"$DUMMY_DMESG_1" <<\EOF ++6,17159,5340096332127,-;usb 1-4: USB disconnect, device number 124 ++6,17160,5340109662397,-;input: WH-1000XM3 (AVRCP) as /devices/virtual/input/input293 ++6,17161,5343126458360,-;loop0: detected capacity change from 0 to 3145728 ++6,17162,5343126766065,-; loop0: p1 p2 ++6,17163,5343126815038,-;EXT4-fs (loop0p1): mounted filesystem with ordered data mode. Quota mode: none. ++6,17164,5343158037334,-;EXT4-fs (loop0p1): unmounting filesystem. ++6,17165,5343158072598,-;loop0: detected capacity change from 0 to 3145728 ++6,17166,5343158073563,-; loop0: p1 p2 ++6,17167,5343158074325,-; loop0: p1 p2 ++6,17168,5343158140859,-;EXT4-fs (loop0p1): mounted filesystem with ordered data mode. Quota mode: none. ++6,17169,5343158182977,-;EXT4-fs (loop0p1): unmounting filesystem. ++6,17170,5343158700241,-;loop0: detected capacity change from 0 to 3145728 ++6,17171,5343158700439,-; loop0: p1 p2 ++6,17172,5343158701120,-; loop0: p1 p2 ++EOF ++ ++DUMMY_DMESG_2="$(mktemp)" ++cat >"$DUMMY_DMESG_2" <<\EOF ++Nechť již hříšné saxofony ďáblů rozezvučí síň úděsnými tóny waltzu, tanga a quickstepu. ++Příliš žluťoučký kůň úpěl ďábelské ódy. ++Zvlášť zákeřný učeň s ďolíčky běží podél zóny úlů. ++Vyciď křišťálový nůž, ó učiň úděsné líbivým! ++Loď čeří kýlem tůň obzvlášť v Grónské úžině ++Ó, náhlý déšť již zvířil prach a čilá laň teď běží s houfcem gazel k úkrytům. ++Vypätá dcéra grófa Maxwella s IQ nižším ako kôň núti čeľaď hrýzť hŕbu jabĺk. ++Kŕdeľ šťastných ďatľov učí pri ústí Váhu mĺkveho koňa obhrýzať kôru a žrať čerstvé mäso. ++Stróż pchnął kość w quiz gędźb vel fax myjń. ++Portez ce vieux whisky au juge blond qui fume! ++EOF ++ ++file_count() { find "${1:?}" -type f | wc -l; } ++file_size() { wc -l <"${1:?}"; } ++random_efi_timestamp() { printf "%0.10d" "$((1000000000 + RANDOM))"; } ++ ++# The dmesg- filename contains the backend-type and the Common Platform Error Record, CPER, ++# record id, a 64-bit number. ++# ++# Files are processed in reverse lexigraphical order so as to properly reconstruct original dmesg. ++ ++prepare_efi_logs() { ++ local file="${1:?}" ++ local timestamp="${2:?}" ++ local chunk count filename ++ ++ # For the EFI backend, the 3 least significant digits of record id encodes a ++ # "count" number, the next 2 least significant digits for the dmesg part ++ # (chunk) number, and the remaining digits as the timestamp. See ++ # linux/drivers/firmware/efi/efi-pstore.c in efi_pstore_write(). ++ count="$(file_size "$file")" ++ chunk=0 ++ # The sed in the process substitution below just reverses the file ++ while read -r line; do ++ filename="$(printf "dmesg-efi-%0.10d%0.2d%0.3d" "$timestamp" "$chunk" "$count")" ++ echo "$line" >"/sys/fs/pstore/$filename" ++ chunk=$((chunk + 1)) ++ done < <(sed '1!G;h;$!d' "$file") ++ ++ if [[ "$chunk" -eq 0 ]]; then ++ echo >&2 "No dmesg-efi files were created" ++ exit 1 ++ fi ++} ++ ++prepare_erst_logs() { ++ local file="${1:?}" ++ local start_id="${2:?}" ++ local id filename ++ ++ # For the ERST backend, the record is a monotonically increasing number, seeded as ++ # a timestamp. See linux/drivers/acpi/apei/erst.c in erst_writer(). ++ id="$start_id" ++ # The sed in the process substitution below just reverses the file ++ while read -r line; do ++ filename="$(printf "dmesg-erst-%0.16d" "$id")" ++ echo "$line" >"/sys/fs/pstore/$filename" ++ id=$((id + 1)) ++ done < <(sed '1!G;h;$!d' "$file") ++ ++ if [[ "$id" -eq "$start_id" ]]; then ++ echo >&2 "No dmesg-erst files were created" ++ exit 1 ++ fi ++ ++ # ID of the last dmesg file will be the ID of the erst subfolder ++ echo "$((id - 1))" ++} ++ ++prepare_pstore_config() { ++ local storage="${1:?}" ++ local unlink="${2:?}" ++ ++ systemctl stop systemd-pstore ++ ++ rm -fr /sys/fs/pstore/* /var/lib/systemd/pstore/* ++ ++ mkdir -p /run/systemd/pstore.conf.d ++ cat >"/run/systemd/pstore.conf.d/99-test.conf" </sys/fs/pstore/foo.bar ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ filename_1="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_1" "$(file_size "$DUMMY_DMESG_1")")" ++ diff "$DUMMY_DMESG_1" "$filename_1" ++ filename_2="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_2" "$(file_size "$DUMMY_DMESG_2")")" ++ diff "$DUMMY_DMESG_2" "$filename_2" ++ grep "hello world" "/var/lib/systemd/pstore/foo.bar" ++ ++ : "Backend: EFI; Storage: journal; Unlink: $unlink" ++ timestamp="$(random_efi_timestamp)" ++ prepare_pstore_config "journal" "$unlink" ++ prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]] ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++ ++ : "Backend: ERST; Storage: external; Unlink: $unlink" ++ prepare_pstore_config "external" "$unlink" ++ last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ # We always log to journal ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++ filename="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id")" ++ diff "$DUMMY_DMESG_1" "$filename" ++ ++ : "Backend: ERST; Storage: external; Unlink: $unlink; multiple dmesg files" ++ prepare_pstore_config "external" "$unlink" ++ last_id_1="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ last_id_2="$(prepare_erst_logs "$DUMMY_DMESG_2" "$((last_id_1 + 10))")" ++ # Add one "random" (non-dmesg) file as well ++ echo "hello world" >/sys/fs/pstore/foo.bar ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]] ++ filename_1="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_1")" ++ diff "$DUMMY_DMESG_1" "$filename_1" ++ filename_2="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_2")" ++ diff "$DUMMY_DMESG_2" "$filename_2" ++ grep "hello world" "/var/lib/systemd/pstore/foo.bar" ++ ++ : "Backend: ERST; Storage: journal; Unlink: $unlink" ++ prepare_pstore_config "journal" "$unlink" ++ last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)" ++ [[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)" ++ start_pstore ++ [[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]] ++ [[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]] ++ diff "$DUMMY_DMESG_1" <(journalctl -o json --after-cursor="${JOURNAL_CURSOR:?}" | jq -r 'select(.FILE) | .FILE' | sed '/^$/d') ++done +diff --git a/test/TEST-74-AUX-UTILS/testsuite.sh b/test/TEST-74-AUX-UTILS/testsuite.sh +new file mode 100755 +index 0000000000..13c767e490 +--- /dev/null ++++ b/test/TEST-74-AUX-UTILS/testsuite.sh +@@ -0,0 +1,14 @@ ++#!/usr/bin/env bash ++# SPDX-License-Identifier: LGPL-2.1-or-later ++set -eux ++set -o pipefail ++ ++: >/failed ++ ++for script in "${0%.sh}".*.sh; do ++ echo "Running $script" ++ "./$script" ++done ++ ++touch /testok ++rm /failed +diff --git a/test/test-functions b/test/test-functions +index a7b18991f4..f0cf6f8575 100644 +--- a/test/test-functions ++++ b/test/test-functions +@@ -23,7 +23,7 @@ fi + + PATH_TO_INIT=$ROOTLIBDIR/systemd + +-BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout" ++BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout jq wc awk diff" + DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" + + STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" diff --git a/0920-ci-update-permissions-for-source-git-automation-work.patch b/0920-ci-update-permissions-for-source-git-automation-work.patch new file mode 100644 index 0000000..2b123bb --- /dev/null +++ b/0920-ci-update-permissions-for-source-git-automation-work.patch @@ -0,0 +1,29 @@ +From ab5a221daca2783b73fd286f5410dbec905cabfa Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 19 May 2023 16:42:03 +0200 +Subject: [PATCH] ci: update permissions for source-git automation workflows + +The new version of `redhat-plumbers-in-action/advanced-commit-linter` requires new permission: `checks: write`. + +https://github.com/redhat-plumbers-in-action/advanced-commit-linter/commit/f1bb35fcdeff83d40eb67b5e7c58baad6be689b2 + +rhel-only + +Related: #2179309 +--- + .github/workflows/source-git-automation.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 140f21b116..e653e28a7f 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -33,7 +33,7 @@ jobs: + validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} + + permissions: +- statuses: write ++ checks: write + pull-requests: write + + steps: diff --git a/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch b/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch new file mode 100644 index 0000000..fa60f26 --- /dev/null +++ b/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch @@ -0,0 +1,130 @@ +From 30cbb55a8d9fedf07d5c9d792849b723b856cd62 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Sun, 12 Feb 2023 12:15:08 +0000 +Subject: [PATCH] sulogin: fix control lost of the current terminal when + default.target is rescue.target + +When default.target is rescue.target, exiting from the single-user shell +results in lost of the control of the current terminal. This is because the +operation performed to continue to boot is systemctl default but default.target +is now rescue.target and it is already active. Hence, no new process that +controls the current terminal is created. Users need to make hardware reset to +recover the situation. + +This sounds like a bit corner case issue and some might feel configuring +default.target as rescue.target is odd because there are several other ways to +transition to rescue.mode without configuring default.target to rescue.target +such as systemctl rescue or systemd.unit=rescue.target something like +that. However, users unfamiliar with systemd operations tend to come up with +systemctl set-default rescue.target. + +To fix this issue, let's transition to default.target only when default.target +is inactive. Otherwise, invoke the single-user shell again to keep control of +the current terminal for users. + +This new logic depends on whether D-Bus working well. Exiting without any check +of result of systemctl default could lead to again the control lost of the +current terminal. Hence, add checking results of each D-Bus operations +including systemctl default and invoke the single-user shell if they fail. + +(cherry picked from commit 937ca8330d11e406b8ef343bead6f4f6244e39c7) + +Resolves: #2169932 +--- + src/sulogin-shell/sulogin-shell.c | 60 +++++++++++++++++++++++++------ + 1 file changed, 50 insertions(+), 10 deletions(-) + +diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c +index a1ea2333de..8f14ee11bb 100644 +--- a/src/sulogin-shell/sulogin-shell.c ++++ b/src/sulogin-shell/sulogin-shell.c +@@ -14,6 +14,8 @@ + #include "process-util.h" + #include "sd-bus.h" + #include "signal-util.h" ++#include "special.h" ++#include "unit-def.h" + + static int reload_manager(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +@@ -43,6 +45,28 @@ static int reload_manager(sd_bus *bus) { + return 0; + } + ++static int default_target_is_inactive(sd_bus *bus) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_free_ char *path = NULL, *state = NULL; ++ int r; ++ ++ path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); ++ if (!path) ++ return log_oom(); ++ ++ r = sd_bus_get_property_string(bus, ++ "org.freedesktop.systemd1", ++ path, ++ "org.freedesktop.systemd1.Unit", ++ "ActiveState", ++ &error, ++ &state); ++ if (r < 0) ++ return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); ++ ++ return streq_ptr(state, "inactive"); ++} ++ + static int start_default_target(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; +@@ -95,7 +119,6 @@ int main(int argc, char *argv[]) { + NULL, /* --force */ + NULL + }; +- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); +@@ -108,17 +131,34 @@ int main(int argc, char *argv[]) { + /* allows passwordless logins if root account is locked. */ + sulogin_cmdline[1] = "--force"; + +- (void) fork_wait(sulogin_cmdline); ++ for (;;) { ++ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; ++ ++ (void) fork_wait(sulogin_cmdline); ++ ++ r = bus_connect_system_systemd(&bus); ++ if (r < 0) { ++ log_warning_errno(r, "Failed to get D-Bus connection: %m"); ++ goto fallback; ++ } + +- r = bus_connect_system_systemd(&bus); +- if (r < 0) { +- log_warning_errno(r, "Failed to get D-Bus connection: %m"); +- r = 0; +- } else { +- (void) reload_manager(bus); ++ if (reload_manager(bus) < 0) ++ goto fallback; + +- r = start_default_target(bus); ++ r = default_target_is_inactive(bus); ++ if (r < 0) ++ goto fallback; ++ if (!r) { ++ log_warning(SPECIAL_DEFAULT_TARGET" is not inactive. Please review the "SPECIAL_DEFAULT_TARGET" setting.\n"); ++ goto fallback; ++ } ++ ++ if (start_default_target(bus) >= 0) ++ break; ++ ++ fallback: ++ log_warning("Fallback to the single-user shell.\n"); + } + +- return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; ++ return 0; + } diff --git a/0922-parse-util-in-parse_permille-check-negative-earlier.patch b/0922-parse-util-in-parse_permille-check-negative-earlier.patch new file mode 100644 index 0000000..2e1065e --- /dev/null +++ b/0922-parse-util-in-parse_permille-check-negative-earlier.patch @@ -0,0 +1,49 @@ +From cb99c3e54af1ba7c6cf1cd99d61546f5aa9423cb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:50:25 +0200 +Subject: [PATCH] parse-util: in parse_permille() check negative earlier + +If 'v' is negative, it's wrong to add the decimal to it, as we'd +actually need to subtract it in this case. But given that we don't want +to allow negative vaues anyway, simply check earlier whether what we +have parsed so far was negative, and react to that before adding the +decimal to it. + +(cherry picked from commit 8cbc92d5975b603002c3141364a7709a9c66e23a) + +Related: #2178179 +--- + src/basic/parse-util.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 992ea3605b..2ab8e88451 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -728,6 +728,8 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + } else { + pc = endswith(p, "%"); + if (!pc) +@@ -748,15 +750,14 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + if (v > (INT_MAX - q) / 10) + return -ERANGE; + + v = v * 10 + q; + } + +- if (v < 0) +- return -ERANGE; +- + return v; + } + diff --git a/0923-tree-wide-increase-granularity-of-percent-specificat.patch b/0923-tree-wide-increase-granularity-of-percent-specificat.patch new file mode 100644 index 0000000..5e53d2a --- /dev/null +++ b/0923-tree-wide-increase-granularity-of-percent-specificat.patch @@ -0,0 +1,165 @@ +From 30343fc0ba66dd7a513de736c7708702ec5400be Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:52:42 +0200 +Subject: [PATCH] tree-wide: increase granularity of percent specifications all + over the place to permille + +We so far had various placed we'd parse percentages with +parse_percent(). Let's make them use parse_permille() instead, which is +downward compatible (as it also parses percent values), and increases +the granularity a bit. Given that on the wire we usually normalize +relative specifications to something like UINT32_MAX anyway changing +from base-100 to base-1000 calculations can be done easily without +breaking compat. + +This commit doesn't document this change in the man pages. While +allowing more precise specifcations permille is not as commonly +understood as perent I guess, hence let's keep this out of the docs for +now. + +(cherry picked from commit f806dfd34595dac8632ba777250323a4735568dc) + +Resolves: #2178179 +--- + src/core/load-fragment.c | 12 ++++++------ + src/login/logind-user.c | 6 +++--- + src/login/pam_systemd.c | 4 ++-- + src/shared/bus-unit-util.c | 22 ++++++++++++---------- + 4 files changed, 23 insertions(+), 21 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 53de7ff5e9..f6505cf83c 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -2991,13 +2991,13 @@ int config_parse_cpu_quota( + return 0; + } + +- r = parse_percent_unbounded(rvalue); ++ r = parse_permille_unbounded(rvalue); + if (r <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU quota '%s', ignoring.", rvalue); + return 0; + } + +- c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 100U; ++ c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 1000U; + return 0; + } + +@@ -3057,7 +3057,7 @@ int config_parse_memory_limit( + + if (!isempty(rvalue) && !streq(rvalue, "infinity")) { + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = parse_size(rvalue, 1024, &bytes); + if (r < 0) { +@@ -3065,7 +3065,7 @@ int config_parse_memory_limit( + return 0; + } + } else +- bytes = physical_memory_scale(r, 100U); ++ bytes = physical_memory_scale(r, 1000U); + + if (bytes >= UINT64_MAX || + (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { +@@ -3132,7 +3132,7 @@ int config_parse_tasks_max( + return 0; + } + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = safe_atou64(rvalue, &v); + if (r < 0) { +@@ -3140,7 +3140,7 @@ int config_parse_tasks_max( + return 0; + } + } else +- v = system_tasks_max_scale(r, 100U); ++ v = system_tasks_max_scale(r, 1000U); + + if (v <= 0 || v >= UINT64_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index bba3158d1a..00d25d5876 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -794,9 +794,9 @@ int config_parse_tmpfs_size( + assert(data); + + /* First, try to parse as percentage */ +- r = parse_percent(rvalue); +- if (r > 0 && r < 100) +- *sz = physical_memory_scale(r, 100U); ++ r = parse_permille(rvalue); ++ if (r > 0 && r < 1000) ++ *sz = physical_memory_scale(r, 1000U); + else { + uint64_t k; + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index c87e980b18..7a551a41bb 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -208,9 +208,9 @@ static int append_session_memory_max(pam_handle_t *handle, sd_bus_message *m, co + return r; + } + } else { +- r = parse_percent(limit); ++ r = parse_permille(limit); + if (r >= 0) { +- r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r)); + return r; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index c475bbafe0..aa4286ab6e 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -440,16 +440,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- r = parse_percent(eq); ++ r = parse_permille(eq); + if (r >= 0) { + char *n; + +- /* When this is a percentage we'll convert this into a relative value in the range +- * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related +- * ones). This way the physical memory size can be determined server-side */ ++ /* When this is a percentage we'll convert this into a relative value in the range 0…UINT32_MAX ++ * and pass it in the MemoryLowScale property (and related ones). This way the physical memory ++ * size can be determined server-side. */ + + n = strjoina(field, "Scale"); +- r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) + return bus_log_create_error(r); + +@@ -467,13 +467,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); + else { +- r = parse_percent_unbounded(eq); +- if (r <= 0) { +- log_error_errno(r, "CPU quota '%s' invalid.", eq); +- return -EINVAL; ++ r = parse_permille_unbounded(eq); ++ if (r == 0) { ++ log_error("CPU quota too small."); ++ return -ERANGE; + } ++ if (r < 0) ++ return log_error_errno(r, "CPU quota '%s' invalid.", eq); + +- r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U); ++ r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (((uint64_t) r * USEC_PER_SEC) / 1000U)); + } + + if (r < 0) diff --git a/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch b/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..abed63e --- /dev/null +++ b/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,31 @@ +From 5a1d30b9a775a7bbac55752abdc10ed5383d209f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:39:35 +0900 +Subject: [PATCH] errno-util: introduce ERRNO_IS_TRANSIENT() + +(cherry picked from commit 7aad83580fccee926d903bdb1a2a6af2c40ef0fc) + +Related: #2172846 +--- + src/basic/util.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 195f02cf5f..48beb88bac 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -180,6 +180,14 @@ static inline int negative_errno(void) { + return -errno; + } + ++ ++/* For send()/recv() or read()/write(). */ ++static inline bool ERRNO_IS_TRANSIENT(int r) { ++ return IN_SET(abs(r), ++ EAGAIN, ++ EINTR); ++} ++ + /* Two different errors for access problems */ + static inline bool ERRNO_IS_PRIVILEGE(int r) { + return IN_SET(abs(r), diff --git a/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch b/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..2c0b3b1 --- /dev/null +++ b/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,545 @@ +From da79f303ec02fdb9a1c07e0fe48e0aaf4bd09e1b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 04:07:24 +0900 +Subject: [PATCH] tree-wide: use ERRNO_IS_TRANSIENT() + +(cherry picked from commit 8add30a03cb19e4a2722fa5a0fc08c277aaf67fd) + +Related: #2172846 +--- + src/basic/barrier.c | 7 ++++--- + src/basic/terminal-util.c | 2 +- + src/core/cgroup.c | 2 +- + src/core/manager.c | 17 ++++++++--------- + src/core/path.c | 2 +- + src/import/importd.c | 2 +- + src/journal/journald-kmsg.c | 2 +- + src/journal/journald-server.c | 2 +- + src/journal/journald-stream.c | 2 +- + src/journal/sd-journal.c | 2 +- + src/libsystemd-network/icmp6-util.c | 2 +- + src/libsystemd-network/sd-dhcp-client.c | 4 ++-- + src/libsystemd-network/sd-dhcp-server.c | 2 +- + src/libsystemd-network/sd-dhcp6-client.c | 2 +- + src/libsystemd-network/sd-ipv4acd.c | 2 +- + src/libsystemd-network/sd-lldp.c | 2 +- + src/libsystemd/sd-event/sd-event.c | 6 +++--- + src/libsystemd/sd-netlink/netlink-socket.c | 4 ++-- + src/libsystemd/sd-network/sd-network.c | 2 +- + src/nspawn/nspawn.c | 2 +- + src/resolve/resolved-dns-stream.c | 6 +++--- + src/resolve/resolved-dns-stub.c | 2 +- + src/resolve/resolved-manager.c | 2 +- + src/shared/ask-password-api.c | 6 +++--- + src/socket-proxy/socket-proxyd.c | 4 ++-- + src/time-wait-sync/time-wait-sync.c | 2 +- + .../tty-ask-password-agent.c | 2 +- + src/udev/udevd.c | 2 +- + 28 files changed, 47 insertions(+), 47 deletions(-) + +diff --git a/src/basic/barrier.c b/src/basic/barrier.c +index 587852aac8..d36c6c6f88 100644 +--- a/src/basic/barrier.c ++++ b/src/basic/barrier.c +@@ -13,6 +13,7 @@ + #include "barrier.h" + #include "fd-util.h" + #include "macro.h" ++#include "util.h" + + /** + * Barriers +@@ -181,7 +182,7 @@ static bool barrier_write(Barrier *b, uint64_t buf) { + assert(b->me >= 0); + do { + len = write(b->me, &buf, sizeof(buf)); +- } while (len < 0 && IN_SET(errno, EAGAIN, EINTR)); ++ } while (len < 0 && ERRNO_IS_TRANSIENT(errno)); + + if (len != sizeof(buf)) + goto error; +@@ -223,7 +224,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + int r; + + r = poll(pfd, 2, -1); +- if (r < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (r < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + else if (r < 0) + goto error; +@@ -233,7 +234,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + + /* events on @them signal new data for us */ + len = read(b->them, &buf, sizeof(buf)); +- if (len < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (len < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + + if (len != sizeof(buf)) +diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c +index e2bbe8187d..18176cfe17 100644 +--- a/src/basic/terminal-util.c ++++ b/src/basic/terminal-util.c +@@ -460,7 +460,7 @@ int acquire_terminal( + + l = read(notify, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f89bce3d61..0c8a66edd1 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2356,7 +2356,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read control group inotify events: %m"); +diff --git a/src/core/manager.c b/src/core/manager.c +index 4a9f9bfcf9..e09227d5ac 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2331,7 +2331,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t + + n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; /* Spurious wakeup, try again */ + + /* If this is any other, real error, then let's stop processing this socket. This of course means we +@@ -2573,19 +2573,18 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t + } + + n = read(m->signal_fd, &sfsi, sizeof(sfsi)); +- if (n != sizeof(sfsi)) { +- if (n >= 0) { +- log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); +- return 0; +- } +- +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (n < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + /* We return an error here, which will kill this handler, + * to avoid a busy loop on read error. */ + return log_error_errno(errno, "Reading from signal fd failed: %m"); + } ++ if (n != sizeof(sfsi)) { ++ log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); ++ return 0; ++ } + + log_received_signal(sfsi.ssi_signo == SIGCHLD || + (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) +@@ -4453,7 +4452,7 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re + + l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read from user lookup fd: %m"); +diff --git a/src/core/path.c b/src/core/path.c +index b899bde0de..dfa63d5102 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -152,7 +152,7 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) { + + l = read(s->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read inotify event: %m"); +diff --git a/src/import/importd.c b/src/import/importd.c +index 04563fb098..5463bd7146 100644 +--- a/src/import/importd.c ++++ b/src/import/importd.c +@@ -519,7 +519,7 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return -errno; +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 726c006ce1..a49cc5c4c5 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -321,7 +321,7 @@ static int server_read_dev_kmsg(Server *s) { + return 0; + } + +- if (IN_SET(errno, EAGAIN, EINTR, EPIPE)) ++ if (ERRNO_IS_TRANSIENT(errno) || errno == EPIPE) + return 0; + + return log_error_errno(errno, "Failed to read from kernel: %m"); +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 4788ff78bb..1e00e4b4bd 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1131,7 +1131,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_error_errno(errno, "recvmsg() failed: %m"); +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 5be5b0939c..470d2e2661 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -556,7 +556,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + + l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_warning_errno(errno, "Failed to read from stream: %m"); +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 4c502978de..ca083da161 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -2563,7 +2563,7 @@ _public_ int sd_journal_process(sd_journal *j) { + + l = read(j->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return got_something ? determine_change(j) : SD_JOURNAL_NOP; + + return -errno; +diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c +index 736df222f0..17d4d1faf2 100644 +--- a/src/libsystemd-network/icmp6-util.c ++++ b/src/libsystemd-network/icmp6-util.c +@@ -175,7 +175,7 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, + + len = recvmsg(fd, &msg, MSG_DONTWAIT); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c +index ff434f8ce7..8a8d806b3f 100644 +--- a/src/libsystemd-network/sd-dhcp-client.c ++++ b/src/libsystemd-network/sd-dhcp-client.c +@@ -1720,7 +1720,7 @@ static int client_receive_message_udp( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +@@ -1814,7 +1814,7 @@ static int client_receive_message_raw( + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c +index 5ca46b3502..c964b73da1 100644 +--- a/src/libsystemd-network/sd-dhcp-server.c ++++ b/src/libsystemd-network/sd-dhcp-server.c +@@ -962,7 +962,7 @@ static int server_receive_message(sd_event_source *s, int fd, + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c +index b3bc259280..67257f2e03 100644 +--- a/src/libsystemd-network/sd-dhcp6-client.c ++++ b/src/libsystemd-network/sd-dhcp6-client.c +@@ -1055,7 +1055,7 @@ static int client_receive_message( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m"); +diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c +index a40d40db90..f69810c6f5 100644 +--- a/src/libsystemd-network/sd-ipv4acd.c ++++ b/src/libsystemd-network/sd-ipv4acd.c +@@ -336,7 +336,7 @@ static int ipv4acd_on_packet( + + n = recv(fd, &packet, sizeof(struct ether_arp), 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m"); +diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c +index c75d6079e1..bf15029027 100644 +--- a/src/libsystemd-network/sd-lldp.c ++++ b/src/libsystemd-network/sd-lldp.c +@@ -200,7 +200,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v + + length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT); + if (length < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 2c9d331bf2..549103bc6f 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3007,7 +3007,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) { + + ss = read(fd, &x, sizeof(x)); + if (ss < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +@@ -3161,7 +3161,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { + + n = read(d->fd, &si, sizeof(si)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return read_one; + + return -errno; +@@ -3210,7 +3210,7 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t + + n = read(d->fd, &d->buffer, sizeof(d->buffer)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c +index f103cbedea..5fe91450a7 100644 +--- a/src/libsystemd/sd-netlink/netlink-socket.c ++++ b/src/libsystemd/sd-netlink/netlink-socket.c +@@ -265,7 +265,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + else if (errno == EAGAIN) + log_debug("rtnl: no data in socket"); + +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + if (sender.nl.nl_pid != 0) { +@@ -276,7 +276,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + /* drop the message */ + n = recvmsg(fd, &msg, 0); + if (n < 0) +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + return 0; +diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c +index 3b8ce935b0..09d3b86e14 100644 +--- a/src/libsystemd/sd-network/sd-network.c ++++ b/src/libsystemd/sd-network/sd-network.c +@@ -338,7 +338,7 @@ _public_ int sd_network_monitor_flush(sd_network_monitor *m) { + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 8cb7591f0e..025a513def 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -3252,7 +3252,7 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_warning_errno(errno, "Couldn't read notification socket: %m"); +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index ca0313d1d7..cebaba4207 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -380,7 +380,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_writev(s, iov, 2, 0); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else + s->n_written += ss; +@@ -402,7 +402,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_read(s, (uint8_t*) &s->read_size + s->n_read, sizeof(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +@@ -452,7 +452,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + (uint8_t*) DNS_PACKET_DATA(s->read_packet) + s->n_read - sizeof(s->read_size), + sizeof(s->read_size) + be16toh(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(errno, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(errno)) + return dns_stream_complete(s, errno); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c +index 5ddf13081e..1b80c42174 100644 +--- a/src/resolve/resolved-dns-stub.c ++++ b/src/resolve/resolved-dns-stub.c +@@ -458,7 +458,7 @@ static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (cfd < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 01372fc66b..2a23c387a6 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -755,7 +755,7 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + if (l == 0) + return 0; + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c +index 764ebd08e1..062db31bbd 100644 +--- a/src/shared/ask-password-api.c ++++ b/src/shared/ask-password-api.c +@@ -332,7 +332,7 @@ int ask_password_tty( + + n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -652,7 +652,7 @@ int ask_password_agent( + + n = recvmsg(socket_fd, &msghdr, 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -661,7 +661,7 @@ int ask_password_agent( + + cmsg_close_all(&msghdr); + +- if (n <= 0) { ++ if (n == 0) { + log_debug("Message too short"); + continue; + } +diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c +index 3d07483eb4..155631f1e7 100644 +--- a/src/socket-proxy/socket-proxyd.c ++++ b/src/socket-proxy/socket-proxyd.c +@@ -144,7 +144,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *from_source = sd_event_source_unref(*from_source); + *from = safe_close(*from); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + +@@ -156,7 +156,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *to_source = sd_event_source_unref(*to_source); + *to = safe_close(*to); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + } while (shoveled); +diff --git a/src/time-wait-sync/time-wait-sync.c b/src/time-wait-sync/time-wait-sync.c +index d268fb0c5a..2071cb2759 100644 +--- a/src/time-wait-sync/time-wait-sync.c ++++ b/src/time-wait-sync/time-wait-sync.c +@@ -94,7 +94,7 @@ static int inotify_handler(sd_event_source *s, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_warning_errno(errno, "Lost access to inotify: %m"); +diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c +index 40d594896b..3a20a381c9 100644 +--- a/src/tty-ask-password-agent/tty-ask-password-agent.c ++++ b/src/tty-ask-password-agent/tty-ask-password-agent.c +@@ -150,7 +150,7 @@ static int ask_password_plymouth( + + k = read(fd, buffer + p, sizeof(buffer) - p); + if (k < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 34f6a95503..172d21018e 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1119,7 +1119,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 1; + + return log_error_errno(errno, "Failed to read inotify fd: %m"); diff --git a/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch b/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch new file mode 100644 index 0000000..b24f961 --- /dev/null +++ b/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch @@ -0,0 +1,75 @@ +From 4cbf11180cc6c6792f541a861f3309c34c156f4b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:33:55 +0900 +Subject: [PATCH] libsystemd: ignore both EINTR and EAGAIN + +(cherry picked from commit b3d06b9226db96fddb6bb45a4708e2e8d413d91d) + +Related: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 8 ++++---- + src/libsystemd/sd-resolve/sd-resolve.c | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 8813dd5efd..c6e1a1624f 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -155,7 +155,7 @@ static int bus_socket_write_auth(sd_bus *b) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k); + return 1; +@@ -573,7 +573,7 @@ static int bus_socket_read_auth(sd_bus *b) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +@@ -1051,7 +1051,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + *idx += (size_t) k; + return 1; +@@ -1205,7 +1205,7 @@ int bus_socket_read_message(sd_bus *bus) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c +index a189f140f8..99ecb6a467 100644 +--- a/src/libsystemd/sd-resolve/sd-resolve.c ++++ b/src/libsystemd/sd-resolve/sd-resolve.c +@@ -402,7 +402,7 @@ static void* thread_worker(void *p) { + + length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0); + if (length < 0) { +- if (errno == EINTR) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + break; +@@ -850,7 +850,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) { + + l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0); + if (l < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; diff --git a/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch b/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch new file mode 100644 index 0000000..160c031 --- /dev/null +++ b/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch @@ -0,0 +1,90 @@ +From b1075e8b3ecb9e0770dd46331ce8517ea152e1ca Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Nov 2022 17:42:04 +0100 +Subject: [PATCH] sd-bus: handle -EINTR return from bus_poll() + +In sd_bus_wait(), let's convert EINTR to a return code of 0, thus asking +the caller do loop again and enter sd_bus_process() again (which will +not find any queued events). This way we'll not return an error on +something that isn't really an error. This should typically make sure +things are properly handled by the caller, magically, without eating up +the event entirely, and still giving the caller time to run some code if +they want. + +(cherry picked from commit 3022916b4d2483452c3ddbbac9ee7c4372b1cb46) + +Resolves: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 5 ++++- + src/libsystemd/sd-bus/sd-bus.c | 18 +++++++++++++++--- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index c6e1a1624f..a5c750fc69 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1266,8 +1266,11 @@ int bus_socket_process_opening(sd_bus *b) { + assert(b->state == BUS_OPENING); + + r = poll(&p, 1, 0); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) ++ return 0; + return -errno; ++ } + + if (!(p.revents & (POLLOUT|POLLERR|POLLHUP))) + return 0; +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 21e54591f7..5d934cbf73 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2209,8 +2209,11 @@ _public_ int sd_bus_call( + left = (uint64_t) -1; + + r = bus_poll(bus, true, left); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + goto fail; ++ } + if (r == 0) { + r = -ETIMEDOUT; + goto fail; +@@ -3069,6 +3072,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { + } + + _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { ++ int r; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); +@@ -3083,7 +3087,11 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { + if (bus->rqueue_size > 0) + return 0; + +- return bus_poll(bus, false, timeout_usec); ++ r = bus_poll(bus, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) ++ return 1; /* treat EINTR as success, but let's exit, so that the caller will call back into us soon. */ ++ ++ return r; + } + + _public_ int sd_bus_flush(sd_bus *bus) { +@@ -3125,8 +3133,12 @@ _public_ int sd_bus_flush(sd_bus *bus) { + return 0; + + r = bus_poll(bus, false, (uint64_t) -1); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; ++ + return r; ++ } + } + } + diff --git a/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch b/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch new file mode 100644 index 0000000..2bc16f7 --- /dev/null +++ b/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch @@ -0,0 +1,28 @@ +From 9ddb41dd9dc3bac57d6c3e05700485ee98df3e17 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:18:07 +0100 +Subject: [PATCH] stdio-bridge: don't be bothered with EINTR + +We handle signals via signal handlers, hence no need to be concerned +about EINTR. + +(cherry picked from commit 7c75f34131772781f690860de797d3e35fd0bed9) + +Related: #2172846 +--- + src/stdio-bridge/stdio-bridge.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c +index 519a92a094..493117ef95 100644 +--- a/src/stdio-bridge/stdio-bridge.c ++++ b/src/stdio-bridge/stdio-bridge.c +@@ -276,6 +276,8 @@ int main(int argc, char *argv[]) { + r = ppoll(p, ELEMENTSOF(p), ts, NULL); + } + if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) /* don't be bothered by signals, i.e. EINTR */ ++ continue; + log_error_errno(errno, "ppoll() failed: %m"); + goto finish; + } diff --git a/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch b/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch new file mode 100644 index 0000000..94f1ebb --- /dev/null +++ b/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch @@ -0,0 +1,36 @@ +From da367d5c87c039f4d1250c12097a5fb16f179a70 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 13:00:48 +0100 +Subject: [PATCH] sd-netlink: handle EINTR from poll() gracefully, as success + +(cherry picked from commit 69858785335afffc51bc03127beb53332c0fb983) + +Related: #2172846 +--- + src/libsystemd/sd-netlink/sd-netlink.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c +index a177f220ab..09900d577b 100644 +--- a/src/libsystemd/sd-netlink/sd-netlink.c ++++ b/src/libsystemd/sd-netlink/sd-netlink.c +@@ -488,13 +488,18 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) { + } + + int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) { ++ int r; ++ + assert_return(nl, -EINVAL); + assert_return(!rtnl_pid_changed(nl), -ECHILD); + + if (nl->rqueue_size > 0) + return 0; + +- return rtnl_poll(nl, false, timeout_usec); ++ r = rtnl_poll(nl, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) /* Convert EINTR to "something happened" and give user a chance to run some code before calling back into us */ ++ return 1; ++ return r; + } + + static int timeout_compare(const void *a, const void *b) { diff --git a/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch b/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch new file mode 100644 index 0000000..381f651 --- /dev/null +++ b/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch @@ -0,0 +1,79 @@ +From 1316ec49f209e31799d42d114bd7f35d5acbe097 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:28:19 +0100 +Subject: [PATCH] resolved: handle -EINTR returned from fd_wait_for_event() + better + +We might get signals for various reasons (for example, somebody asking +us to reload caches via a signal), hence let's handle this gracefully. + +(cherry picked from commit 6d66a221685c15798e796d9738f73fdb1fdccdb2) + +Related: #2172846 +--- + src/resolve/resolved-manager.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 2a23c387a6..5583d63527 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -842,11 +842,14 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + } + + static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(mh); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (sendmsg(fd, mh, flags) >= 0) + return 0; +@@ -857,20 +860,26 @@ static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } + } + + static int write_loop(int fd, void *message, size_t length) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(message); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (write(fd, message, length) >= 0) + return 0; +@@ -881,9 +890,12 @@ static int write_loop(int fd, void *message, size_t length) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } diff --git a/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch b/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch new file mode 100644 index 0000000..2d80680 --- /dev/null +++ b/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch @@ -0,0 +1,28 @@ +From c57daab191c6551ac757576fcf7df45fd9790b6b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:38 +0100 +Subject: [PATCH] utmp-wtmp: fix error in case isatty() fails + +(cherry picked from commit 80b780ba178a84b248ecee47eef82358480c9492) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index ef9427fa7b..743b784489 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -312,8 +312,10 @@ static int write_to_terminal(const char *tty, const char *message) { + assert(message); + + fd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); +- if (fd < 0 || !isatty(fd)) ++ if (fd < 0) + return -errno; ++ if (!isatty(fd)) ++ return -ENOTTY; + + p = message; + left = strlen(message); diff --git a/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch b/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch new file mode 100644 index 0000000..6cff781 --- /dev/null +++ b/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch @@ -0,0 +1,52 @@ +From 3590a9c5ce038bc56cdded426156cbd278903c86 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:55 +0100 +Subject: [PATCH] utmp-wtmp: handle EINTR gracefully when waiting to write to + tty + +(cherry picked from commit 22ecfa83123dbfa2322346ac4e25ad2193a3b10c) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index 743b784489..7358ece75d 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -320,7 +320,7 @@ static int write_to_terminal(const char *tty, const char *message) { + p = message; + left = strlen(message); + +- end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC; ++ end = usec_add(now(CLOCK_MONOTONIC), TIMEOUT_MSEC*USEC_PER_MSEC); + + while (left > 0) { + ssize_t n; +@@ -332,20 +332,22 @@ static int write_to_terminal(const char *tty, const char *message) { + int k; + + t = now(CLOCK_MONOTONIC); +- + if (t >= end) + return -ETIME; + + k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC); +- if (k < 0) ++ if (k < 0) { ++ if (ERRNO_IS_TRANSIENT(k)) ++ continue; + return -errno; + ++ } + if (k == 0) + return -ETIME; + + n = write(fd, p, left); + if (n < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; diff --git a/0933-journal-vacuum-count-size-of-all-journal-files.patch b/0933-journal-vacuum-count-size-of-all-journal-files.patch new file mode 100644 index 0000000..48c4403 --- /dev/null +++ b/0933-journal-vacuum-count-size-of-all-journal-files.patch @@ -0,0 +1,90 @@ +From 947296a00d17ef115f4097aa86a8c6f1bfc8bf58 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 22 Mar 2023 12:36:54 +0100 +Subject: [PATCH] journal-vacuum: count size of all journal files + +Currently, active journal files are excluded, which means that vacuuming +may not remove anything even if *MaxUse= has been exceeded. + +(cherry picked from commit 9ea46af4f2368b41d57705bac09774778126507f) + +Resolves: #2180380 +--- + src/journal/journal-vacuum.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c +index 8d3ae71440..dd21f40966 100644 +--- a/src/journal/journal-vacuum.c ++++ b/src/journal/journal-vacuum.c +@@ -179,6 +179,8 @@ int journal_directory_vacuum( + if (!S_ISREG(st.st_mode)) + continue; + ++ size = 512UL * (uint64_t) st.st_blocks; ++ + q = strlen(de->d_name); + + if (endswith(de->d_name, ".journal")) { +@@ -188,6 +190,7 @@ int journal_directory_vacuum( + + if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -195,6 +198,7 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] != '-' || + de->d_name[q-8-16-1-16-1-32-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -207,11 +211,13 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] = 0; + if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { + n_active_files++; ++ sum += size; + continue; + } + + if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -224,12 +230,14 @@ int journal_directory_vacuum( + + if (q < 1 + 16 + 1 + 16 + 8 + 1) { + n_active_files++; ++ sum += size; + continue; + } + + if (de->d_name[q-1-8-16-1] != '-' || + de->d_name[q-1-8-16-1-16-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -241,6 +249,7 @@ int journal_directory_vacuum( + + if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -251,8 +260,6 @@ int journal_directory_vacuum( + continue; + } + +- size = 512UL * (uint64_t) st.st_blocks; +- + r = journal_file_empty(dirfd(d), p); + if (r < 0) { + log_debug_errno(r, "Failed check if %s is empty, ignoring: %m", p); diff --git a/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch b/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch new file mode 100644 index 0000000..3a51892 --- /dev/null +++ b/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch @@ -0,0 +1,365 @@ +From fc8959efebc662f4050700cc1ed2798750b15b73 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 13:32:53 +0100 +Subject: [PATCH] resolved: instead of closing DNS UDP transaction fds + right-away, add them to a socket "graveyard" + +The "socket graveyard" shall contain sockets we have sent a question out +of, but not received a reply. If we'd close thus sockets immediately +when we are not interested anymore, we'd trigger ICMP port unreachable +messages once we after all *do* get a reply. Let's avoid that, by +leaving the fds open for a bit longer, until a timeout is reached or a +reply datagram received. + +Fixes: #17421 +(cherry picked from commit 80710ade03d971a8877fde8ce9d42eb2b07f4c47) + +Resolves: #2156751 +--- + src/resolve/meson.build | 2 + + src/resolve/resolved-dns-transaction.c | 44 ++++++-- + src/resolve/resolved-manager.c | 2 + + src/resolve/resolved-manager.h | 5 + + src/resolve/resolved-socket-graveyard.c | 133 ++++++++++++++++++++++++ + src/resolve/resolved-socket-graveyard.h | 18 ++++ + 6 files changed, 194 insertions(+), 10 deletions(-) + create mode 100644 src/resolve/resolved-socket-graveyard.c + create mode 100644 src/resolve/resolved-socket-graveyard.h + +diff --git a/src/resolve/meson.build b/src/resolve/meson.build +index 15f3835d55..a975e58242 100644 +--- a/src/resolve/meson.build ++++ b/src/resolve/meson.build +@@ -63,6 +63,8 @@ systemd_resolved_sources = files(''' + resolved-dns-stub.c + resolved-etc-hosts.h + resolved-etc-hosts.c ++ resolved-socket-graveyard.c ++ resolved-socket-graveyard.h + '''.split()) + + resolvectl_sources = files(''' +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index c60b8215a6..95aea21134 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -48,7 +48,14 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) { + } + } + +-static void dns_transaction_close_connection(DnsTransaction *t) { ++static void dns_transaction_close_connection( ++ DnsTransaction *t, ++ bool use_graveyard) { /* Set use_graveyard = false when you know the connection is already ++ * dead, for example because you got a connection error back from the ++ * kernel. In that case there's no point in keeping the fd around, ++ * hence don't. */ ++ int r; ++ + assert(t); + + if (t->stream) { +@@ -62,6 +69,20 @@ static void dns_transaction_close_connection(DnsTransaction *t) { + } + + t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source); ++ ++ /* If we have an UDP socket where we sent a packet, but never received one, then add it to the socket ++ * graveyard, instead of closing it right away. That way it will stick around for a moment longer, ++ * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP ++ * port unreachable error message. */ ++ ++ if (use_graveyard && t->dns_udp_fd >= 0 && t->sent && !t->received) { ++ r = manager_add_socket_to_graveyard(t->scope->manager, t->dns_udp_fd); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add UDP socket to graveyard, closing immediately: %m"); ++ else ++ TAKE_FD(t->dns_udp_fd); ++ } ++ + t->dns_udp_fd = safe_close(t->dns_udp_fd); + } + +@@ -81,7 +102,7 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) { + + log_debug("Freeing transaction %" PRIu16 ".", t->id); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + dns_packet_unref(t->sent); +@@ -341,7 +362,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { + + t->state = state; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + /* Notify all queries that are interested, but make sure the +@@ -455,7 +476,7 @@ static int dns_transaction_maybe_restart(DnsTransaction *t) { + static void on_transaction_stream_error(DnsTransaction *t, int error) { + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (ERRNO_IS_DISCONNECT(error)) { + if (t->scope->protocol == DNS_PROTOCOL_LLMNR) { +@@ -478,7 +499,7 @@ static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) { + assert(t); + assert(p); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (dns_packet_validate_reply(p) <= 0) { + log_debug("Invalid TCP reply packet."); +@@ -583,7 +604,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + switch (t->scope->protocol) { + +@@ -692,7 +713,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + r = dns_stream_write_packet(t->stream, t->sent); + if (r < 0) { +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, /* use_graveyard= */ false); + return r; + } + +@@ -1196,7 +1217,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { + if (r > 0) { + /* There are DNSSEC transactions pending now. Update the state accordingly. */ + t->state = DNS_TRANSACTION_VALIDATING; +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + return; + } +@@ -1277,7 +1298,10 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */ + int fd; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); ++ ++ /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */ ++ manager_socket_graveyard_process(t->scope->manager); + + fd = dns_scope_socket_udp(t->scope, t->server, 53); + if (fd < 0) +@@ -1297,7 +1321,7 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r < 0) + return r; + } else +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent); + if (r < 0) +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 5583d63527..5feb92a676 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -683,6 +683,8 @@ Manager *manager_free(Manager *m) { + manager_mdns_stop(m); + manager_dns_stub_stop(m); + ++ manager_socket_graveyard_clear(m); ++ + sd_bus_slot_unref(m->prepare_for_sleep_slot); + sd_bus_unref(m->bus); + +diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h +index d94b2888ab..80119bfcb3 100644 +--- a/src/resolve/resolved-manager.h ++++ b/src/resolve/resolved-manager.h +@@ -20,6 +20,7 @@ typedef struct Manager Manager; + #include "resolved-dns-stream.h" + #include "resolved-dns-trust-anchor.h" + #include "resolved-link.h" ++#include "resolved-socket-graveyard.h" + + #define MANAGER_SEARCH_DOMAINS_MAX 32 + #define MANAGER_DNS_SERVERS_MAX 32 +@@ -130,6 +131,10 @@ struct Manager { + sd_event_source *dns_stub_tcp_event_source; + + Hashmap *polkit_registry; ++ ++ LIST_HEAD(SocketGraveyard, socket_graveyard); ++ SocketGraveyard *socket_graveyard_oldest; ++ size_t n_socket_graveyard; + }; + + /* Manager */ +diff --git a/src/resolve/resolved-socket-graveyard.c b/src/resolve/resolved-socket-graveyard.c +new file mode 100644 +index 0000000000..067cb666d4 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.c +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "resolved-socket-graveyard.h" ++ ++#define SOCKET_GRAVEYARD_USEC (5 * USEC_PER_SEC) ++#define SOCKET_GRAVEYARD_MAX 100 ++ ++/* This implements a socket "graveyard" for UDP sockets. If a socket fd is added to the graveyard it is kept ++ * open for a couple of more seconds, expecting one reply. Once the reply is received the fd is closed ++ * immediately, or if none is received it is closed after the timeout. Why all this? So that if we contact a ++ * DNS server, and it doesn't reply instantly, and we lose interest in the response and thus close the fd, we ++ * don't end up sending back an ICMP error once the server responds but we aren't listening anymore. (See ++ * https://github.com/systemd/systemd/issues/17421 for further information.) ++ * ++ * Note that we don't allocate any timer event source to clear up the graveyard once the socket's timeout is ++ * reached. Instead we operate lazily: we close old entries when adding a new fd to the graveyard, or ++ * whenever any code runs manager_socket_graveyard_process() — which the DNS transaction code does right ++ * before allocating a new UDP socket. */ ++ ++static SocketGraveyard* socket_graveyard_free(SocketGraveyard *g) { ++ if (!g) ++ return NULL; ++ ++ if (g->manager) { ++ assert(g->manager->n_socket_graveyard > 0); ++ g->manager->n_socket_graveyard--; ++ ++ if (g->manager->socket_graveyard_oldest == g) ++ g->manager->socket_graveyard_oldest = g->graveyard_prev; ++ ++ LIST_REMOVE(graveyard, g->manager->socket_graveyard, g); ++ ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard); ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard_oldest); ++ } ++ ++ if (g->io_event_source) { ++ log_debug("Closing graveyard socket fd %i", sd_event_source_get_io_fd(g->io_event_source)); ++ sd_event_source_unref(g->io_event_source); ++ } ++ ++ return mfree(g); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(SocketGraveyard*, socket_graveyard_free); ++ ++void manager_socket_graveyard_process(Manager *m) { ++ usec_t n = USEC_INFINITY; ++ ++ assert(m); ++ ++ while (m->socket_graveyard_oldest) { ++ SocketGraveyard *g = m->socket_graveyard_oldest; ++ ++ if (n == USEC_INFINITY) ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &n) >= 0); ++ ++ if (g->deadline > n) ++ break; ++ ++ socket_graveyard_free(g); ++ } ++} ++ ++void manager_socket_graveyard_clear(Manager *m) { ++ assert(m); ++ ++ while (m->socket_graveyard) ++ socket_graveyard_free(m->socket_graveyard); ++} ++ ++static int on_io_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ SocketGraveyard *g = userdata; ++ ++ assert(g); ++ ++ /* An IO event happened on the graveyard fd. We don't actually care which event that is, and we don't ++ * read any incoming packet off the socket. We just close the fd, that's enough to not trigger the ++ * ICMP unreachable port event */ ++ ++ socket_graveyard_free(g); ++ return 0; ++} ++ ++static void manager_socket_graveyard_make_room(Manager *m) { ++ assert(m); ++ ++ while (m->n_socket_graveyard >= SOCKET_GRAVEYARD_MAX) ++ socket_graveyard_free(m->socket_graveyard_oldest); ++} ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd) { ++ _cleanup_(socket_graveyard_freep) SocketGraveyard *g = NULL; ++ int r; ++ ++ assert(m); ++ assert(fd >= 0); ++ ++ manager_socket_graveyard_process(m); ++ manager_socket_graveyard_make_room(m); ++ ++ g = new(SocketGraveyard, 1); ++ if (!g) ++ return log_oom(); ++ ++ *g = (SocketGraveyard) { ++ .manager = m, ++ }; ++ ++ LIST_PREPEND(graveyard, m->socket_graveyard, g); ++ if (!m->socket_graveyard_oldest) ++ m->socket_graveyard_oldest = g; ++ ++ m->n_socket_graveyard++; ++ ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &g->deadline) >= 0); ++ g->deadline += SOCKET_GRAVEYARD_USEC; ++ ++ r = sd_event_add_io(m->event, &g->io_event_source, fd, EPOLLIN, on_io_event, g); ++ if (r < 0) ++ return log_error_errno(r, "Failed to create graveyard IO source: %m"); ++ ++ r = sd_event_source_set_io_fd_own(g->io_event_source, true); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enable graveyard IO source fd ownership: %m"); ++ ++ (void) sd_event_source_set_description(g->io_event_source, "graveyard"); ++ ++ log_debug("Added socket %i to graveyard", fd); ++ ++ TAKE_PTR(g); ++ return 0; ++} +diff --git a/src/resolve/resolved-socket-graveyard.h b/src/resolve/resolved-socket-graveyard.h +new file mode 100644 +index 0000000000..9b13bb0482 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++typedef struct SocketGraveyard SocketGraveyard; ++ ++#include "resolved-manager.h" ++ ++struct SocketGraveyard { ++ Manager *manager; ++ usec_t deadline; ++ sd_event_source *io_event_source; ++ LIST_FIELDS(SocketGraveyard, graveyard); ++}; ++ ++void manager_socket_graveyard_process(Manager *m); ++void manager_socket_graveyard_clear(Manager *m); ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd); diff --git a/0935-resolved-close-UDP-socket-when-we-received-a-network.patch b/0935-resolved-close-UDP-socket-when-we-received-a-network.patch new file mode 100644 index 0000000..25c1692 --- /dev/null +++ b/0935-resolved-close-UDP-socket-when-we-received-a-network.patch @@ -0,0 +1,26 @@ +From 648fe0097229c7ae46a6b5911521cef27a726cbe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 14:31:56 +0100 +Subject: [PATCH] resolved: close UDP socket when we received a network error + on it + +(cherry picked from commit d68dbb37d7408c025e736181f294152e2a515bf1) + +Related: #2156751 +--- + src/resolve/resolved-dns-transaction.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index 95aea21134..c975215468 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -1250,6 +1250,8 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use + assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0); + dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level); + ++ dns_transaction_close_connection(t, /* use_graveyard = */ false); ++ + dns_transaction_retry(t, true); + return 0; + } diff --git a/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch b/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch new file mode 100644 index 0000000..342a153 --- /dev/null +++ b/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch @@ -0,0 +1,24 @@ +From 950cc2c5109f269561d3c0fdd020c6bf7cb561e1 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 10 Jul 2023 12:38:05 +0200 +Subject: [PATCH] ci: allow RHEL-only labels to mark downstream-only commits + +RHEL-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 491836abbb..327af0467a 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -6,6 +6,7 @@ policy: + exception: + note: + - rhel-only ++ - RHEL-only + tracker: + - keyword: + - 'Resolves: #?' diff --git a/0937-man-tweak-markup-in-systemd-pstore.service-8.patch b/0937-man-tweak-markup-in-systemd-pstore.service-8.patch new file mode 100644 index 0000000..eec7298 --- /dev/null +++ b/0937-man-tweak-markup-in-systemd-pstore.service-8.patch @@ -0,0 +1,39 @@ +From e3d4d6b36c111c5273ce5da124116f1c98b10d9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:48:44 +0100 +Subject: [PATCH] man: tweak markup in systemd-pstore.service(8) + +(cherry picked from commit e3b192626e24cbd3a4dc2c7d5fb9a3b3fd136e24) + +Related: #2217786 +--- + man/systemd-pstore.xml | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.xml +index dd1aa5e83b..8726071cf0 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.xml +@@ -49,8 +49,8 @@ + + The pstore service is independent of the kdump service. In cloud environments + specifically, host and guest filesystems are on remote filesystems (eg. iSCSI +- or NFS), thus kdump relies [implicitly and/or explicitly] upon proper operation +- of networking software *and* hardware *and* infrastructure. Thus it may not be ++ or NFS), thus kdump relies (implicitly and/or explicitly) upon proper operation ++ of networking software *and* hardware *and* infrastructure. Thus it may not be + possible to capture a kernel coredump to a file since writes over the network + may not be possible. + +@@ -59,9 +59,9 @@ + debugging. + + The systemd-pstore executable does the actual work. Upon starting, +- the pstore.conf is read to obtain options, then the /sys/fs/pstore ++ the pstore.conf file is read and the /sys/fs/pstore + directory contents are processed according to the options. Pstore files are written to the +- journal, and optionally saved into /var/lib/systemd/pstore. ++ journal, and optionally saved into /var/lib/systemd/pstore. + + + diff --git a/0938-man-add-.service-suffix-to-systemd-pstore-8.patch b/0938-man-add-.service-suffix-to-systemd-pstore-8.patch new file mode 100644 index 0000000..2a4f140 --- /dev/null +++ b/0938-man-add-.service-suffix-to-systemd-pstore-8.patch @@ -0,0 +1,61 @@ +From ff17baae0631f42f59be6e425943c7181c6c5c18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:57:06 +0100 +Subject: [PATCH] man: add .service suffix to systemd-pstore(8) + +That is the pattern that we always use with executables not in +$PATH. + +(cherry picked from commit aa07dc70932837bfeda982affe53f01d36ec6efe) + +Related: #2217786 +--- + man/rules/meson.build | 2 +- + man/{systemd-pstore.xml => systemd-pstore.service.xml} | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + rename man/{systemd-pstore.xml => systemd-pstore.service.xml} (95%) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 6295330c5e..05eb0a1604 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -634,7 +634,7 @@ manpages = [ + ['systemd-nspawn', '1', [], ''], + ['systemd-path', '1', [], ''], + ['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'], +- ['systemd-pstore', '8', ['systemd-pstore.service'], 'ENABLE_PSTORE'], ++ ['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'], + ['systemd-quotacheck.service', + '8', + ['systemd-quotacheck'], +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.service.xml +similarity index 95% +rename from man/systemd-pstore.xml +rename to man/systemd-pstore.service.xml +index 8726071cf0..47916da521 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.service.xml +@@ -7,19 +7,19 @@ + xmlns:xi="http://www.w3.org/2001/XInclude"> + + +- systemd-pstore ++ systemd-pstore.service + systemd + + + +- systemd-pstore ++ systemd-pstore.service + 8 + + + +- systemd-pstore + systemd-pstore.service +- Tool to archive contents of the persistent storage filesytem ++ systemd-pstore ++ A service to archive contents of pstore + + + diff --git a/0939-presets-enable-systemd-pstore.service-by-default.patch b/0939-presets-enable-systemd-pstore.service-by-default.patch new file mode 100644 index 0000000..0999eb3 --- /dev/null +++ b/0939-presets-enable-systemd-pstore.service-by-default.patch @@ -0,0 +1,26 @@ +From 36d9a1a50f80322b24ff5756b8fb89a07363dfd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 10:01:39 +0100 +Subject: [PATCH] presets: enable systemd-pstore.service by default + +It has no effect is the pstore is not used, and prevents the non-volatile +storage from filling up if is used by the kernel. + +https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=952767 +(cherry picked from commit 5926ea0a6860095eaa83403417cbbf345db864f6) + +Resolves: #2217786 +--- + presets/90-systemd.preset | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/presets/90-systemd.preset b/presets/90-systemd.preset +index 11960e5423..b8edc23d48 100644 +--- a/presets/90-systemd.preset ++++ b/presets/90-systemd.preset +@@ -34,3 +34,5 @@ disable syslog.socket + disable systemd-journal-gatewayd.* + disable systemd-journal-remote.* + disable systemd-journal-upload.* ++ ++enable systemd-pstore.service diff --git a/0940-logind-simplify-code.patch b/0940-logind-simplify-code.patch new file mode 100644 index 0000000..b1a4a25 --- /dev/null +++ b/0940-logind-simplify-code.patch @@ -0,0 +1,54 @@ +From bf5b87db9785b86fadbd2b5e97e4883cbe51797d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 23 Jun 2022 09:56:33 +0200 +Subject: [PATCH] logind: simplify code + +Follow-up for 4885d7490b23e08d8444e5a68927ce9ce8727e5a. + +(cherry picked from commit e5c09aad375551b9db499703ab7eb123d408ba16) + +Resolves: #2209328 +--- + src/login/logind-session.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 916202a65a..fabf680b61 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -349,12 +349,11 @@ fail: + } + + static int session_load_devices(Session *s, const char *devices) { +- const char *p; + int r = 0; + + assert(s); + +- for (p = devices;;) { ++ for (const char *p = devices;;) { + _cleanup_free_ char *word = NULL; + SessionDevice *sd; + dev_t dev; +@@ -531,7 +530,7 @@ int session_load(Session *s) { + s->class = c; + } + +- if (state && streq(state, "closing")) ++ if (streq_ptr(state, "closing")) + s->stopping = true; + + if (s->fifo_path) { +@@ -1073,11 +1072,8 @@ int session_set_display(Session *s, const char *display) { + assert(s); + assert(display); + +- if (streq(s->display, display)) +- return 0; +- + r = free_and_strdup(&s->display, display); +- if (r < 0) ++ if (r <= 0) /* 0 means the strings were equal */ + return r; + + session_save(s); diff --git a/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch b/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch new file mode 100644 index 0000000..5b62383 --- /dev/null +++ b/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch @@ -0,0 +1,89 @@ +From 2fb7d36caf560e4ce57265673da7a518d7a5348f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 16 Jul 2019 00:44:14 +0900 +Subject: [PATCH] format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE + +(cherry picked from commit c5bbb2b5be079852d92d16ebc0d0840929ed82e1) + +Related: #2156786 +--- + src/basic/format-table.c | 25 ++++++++++++++++++------- + src/basic/format-table.h | 2 ++ + 2 files changed, 20 insertions(+), 7 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index c541e92b3c..5f2e5e3d73 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -236,6 +236,8 @@ static size_t table_data_size(TableDataType type, const void *data) { + return sizeof(bool); + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + return sizeof(usec_t); + +@@ -700,6 +702,8 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { + break; + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + buffer.usec = va_arg(ap, usec_t); + data = &buffer.usec; +@@ -837,11 +841,9 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t + return 0; + + case TABLE_TIMESTAMP: +- if (a->timestamp < b->timestamp) +- return -1; +- if (a->timestamp > b->timestamp) +- return 1; +- return 0; ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: ++ return CMP(a->timestamp, b->timestamp); + + case TABLE_TIMESPAN: + if (a->timespan < b->timespan) +@@ -952,14 +954,23 @@ static const char *table_data_format(TableData *d) { + case TABLE_BOOLEAN: + return yes_no(d->boolean); + +- case TABLE_TIMESTAMP: { ++ case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: { + _cleanup_free_ char *p; ++ char *ret; + + p = new(char, FORMAT_TIMESTAMP_MAX); + if (!p) + return NULL; + +- if (!format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp)) ++ if (d->type == TABLE_TIMESTAMP) ++ ret = format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else if (d->type == TABLE_TIMESTAMP_UTC) ++ ret = format_timestamp_utc(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else ++ ret = format_timestamp_relative(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ if (!ret) + return "n/a"; + + d->formatted = TAKE_PTR(p); +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 5a076b5383..1c8ab5436d 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -12,6 +12,8 @@ typedef enum TableDataType { + TABLE_STRING, + TABLE_BOOLEAN, + TABLE_TIMESTAMP, ++ TABLE_TIMESTAMP_UTC, ++ TABLE_TIMESTAMP_RELATIVE, + TABLE_TIMESPAN, + TABLE_SIZE, + TABLE_UINT32, diff --git a/0942-loginctl-shorten-variable-name.patch b/0942-loginctl-shorten-variable-name.patch new file mode 100644 index 0000000..e959206 --- /dev/null +++ b/0942-loginctl-shorten-variable-name.patch @@ -0,0 +1,39 @@ +From c88514d4de20ceeeea2028917087e2710ea419b2 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 23 May 2023 10:48:15 +0200 +Subject: [PATCH] loginctl: shorten variable name + +(cherry picked from commit 86f128558d57586bd28c55eb63968eab3dc4b36e) + +Related: #2156786 +--- + src/login/loginctl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9b3fed928b..079c0e2b17 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -147,7 +147,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + (void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100); + + for (;;) { +- _cleanup_(sd_bus_error_free) sd_bus_error error_tty = SD_BUS_ERROR_NULL; ++ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; + const char *id, *user, *seat, *object, *tty = NULL; + uint32_t uid; +@@ -164,11 +164,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + object, + "org.freedesktop.login1.Session", + "TTY", +- &error_tty, ++ &e, + &reply_tty, + "s"); + if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&error_tty, r)); ++ log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); + else { + r = sd_bus_message_read(reply_tty, "s", &tty); + if (r < 0) diff --git a/0943-loginctl-use-bus_map_all_properties.patch b/0943-loginctl-use-bus_map_all_properties.patch new file mode 100644 index 0000000..3786b5c --- /dev/null +++ b/0943-loginctl-use-bus_map_all_properties.patch @@ -0,0 +1,137 @@ +From 5d2f49451c5e697d6e3548cfc9087ef3c16aa969 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 13:33:58 +0200 +Subject: [PATCH] loginctl: use bus_map_all_properties + +(cherry picked from commit 5b7d1536d0c2ccf0b7688490f31c92c1e766ea44) + +Related: #2156786 +--- + src/login/loginctl.c | 78 ++++++++++++++++++++++---------------------- + 1 file changed, 39 insertions(+), 39 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 079c0e2b17..9e4c710062 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -47,6 +47,27 @@ static bool arg_ask_password = true; + static unsigned arg_lines = 10; + static OutputMode arg_output = OUTPUT_SHORT; + ++typedef struct SessionStatusInfo { ++ const char *id; ++ uid_t uid; ++ const char *name; ++ struct dual_timestamp timestamp; ++ unsigned int vtnr; ++ const char *seat; ++ const char *tty; ++ const char *display; ++ bool remote; ++ const char *remote_host; ++ const char *remote_user; ++ const char *service; ++ pid_t leader; ++ const char *type; ++ const char *class; ++ const char *state; ++ const char *scope; ++ const char *desktop; ++} SessionStatusInfo; ++ + static OutputFlags get_output_flags(void) { + + return +@@ -112,6 +133,12 @@ static int show_table(Table *table, const char *word) { + } + + static int list_sessions(int argc, char *argv[], void *userdata) { ++ ++ static const struct bus_properties_map map[] = { ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ {}, ++ }; ++ + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(table_unrefp) Table *table = NULL; +@@ -148,9 +175,10 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + for (;;) { + _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; +- const char *id, *user, *seat, *object, *tty = NULL; ++ const char *id, *user, *seat, *object; + uint32_t uid; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; ++ SessionStatusInfo i = {}; + + r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object); + if (r < 0) +@@ -158,21 +186,14 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r == 0) + break; + +- r = sd_bus_get_property( +- bus, +- "org.freedesktop.login1", +- object, +- "org.freedesktop.login1.Session", +- "TTY", +- &e, +- &reply_tty, +- "s"); +- if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); +- else { +- r = sd_bus_message_read(reply_tty, "s", &tty); +- if (r < 0) +- return bus_log_parse_error(r); ++ r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); ++ if (r < 0) { ++ if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) ++ /* The session is already closed when we're querying the property */ ++ continue; ++ ++ log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); + } + + r = table_add_many(table, +@@ -180,7 +201,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(tty)); ++ TABLE_STRING, strna(i.tty)); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } +@@ -341,27 +362,6 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit + return 0; + } + +-typedef struct SessionStatusInfo { +- const char *id; +- uid_t uid; +- const char *name; +- struct dual_timestamp timestamp; +- unsigned int vtnr; +- const char *seat; +- const char *tty; +- const char *display; +- bool remote; +- const char *remote_host; +- const char *remote_user; +- const char *service; +- pid_t leader; +- const char *type; +- const char *class; +- const char *state; +- const char *scope; +- const char *desktop; +-} SessionStatusInfo; +- + typedef struct UserStatusInfo { + uid_t uid; + bool linger; diff --git a/0944-loginctl-show-session-idle-status-in-list-sessions.patch b/0944-loginctl-show-session-idle-status-in-list-sessions.patch new file mode 100644 index 0000000..1edd5e2 --- /dev/null +++ b/0944-loginctl-show-session-idle-status-in-list-sessions.patch @@ -0,0 +1,80 @@ +From 0d1082f3cf9d4028ac69c22e9dad2adb51ee910d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 14:03:09 +0200 +Subject: [PATCH] loginctl: show session idle status in list-sessions + +(cherry picked from commit 556723e738b96a5c2b2d45a96b87b7b80e0c5664) + +Resolves: #2156786 +--- + src/login/loginctl.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9e4c710062..65fe182195 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -66,6 +66,8 @@ typedef struct SessionStatusInfo { + const char *state; + const char *scope; + const char *desktop; ++ bool idle_hint; ++ dual_timestamp idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -135,7 +137,9 @@ static int show_table(Table *table, const char *word) { + static int list_sessions(int argc, char *argv[], void *userdata) { + + static const struct bus_properties_map map[] = { +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -165,7 +169,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r < 0) + return bus_log_parse_error(r); + +- table = table_new("SESSION", "UID", "USER", "SEAT", "TTY"); ++ table = table_new("SESSION", "UID", "USER", "SEAT", "TTY", "IDLE", "SINCE"); + if (!table) + return log_oom(); + +@@ -188,12 +192,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); + if (r < 0) { +- if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) +- /* The session is already closed when we're querying the property */ +- continue; +- +- log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", +- id, bus_error_message(&e, r)); ++ log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING, ++ r, ++ "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); ++ continue; + } + + r = table_add_many(table, +@@ -201,7 +204,15 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(i.tty)); ++ TABLE_STRING, strna(i.tty), ++ TABLE_BOOLEAN, i.idle_hint); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add row to table: %m"); ++ ++ if (i.idle_hint) ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ else ++ r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } diff --git a/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch b/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch new file mode 100644 index 0000000..93a96b5 --- /dev/null +++ b/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch @@ -0,0 +1,53 @@ +From ea3d85221a7ba83ff1d9612d29cc8ca3e054f2fa Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 25 May 2023 01:20:45 +0800 +Subject: [PATCH] loginctl: list-sessions: fix timestamp for idle hint + +Follow-up for 556723e738b96a5c2b2d45a96b87b7b80e0c5664 + +TABLE_TIMESTAMP_RELATIVE takes a realtime timestamp. + +(cherry picked from commit be88af3d9646c8bd1aaea3d4a00520e97ee8674d) + +Related: #2156786 +--- + src/login/loginctl.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 65fe182195..1131267015 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -67,7 +67,7 @@ typedef struct SessionStatusInfo { + const char *scope; + const char *desktop; + bool idle_hint; +- dual_timestamp idle_hint_timestamp; ++ usec_t idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -136,10 +136,10 @@ static int show_table(Table *table, const char *word) { + + static int list_sessions(int argc, char *argv[], void *userdata) { + +- static const struct bus_properties_map map[] = { +- { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, +- { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ static const struct bus_properties_map map[] = { ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -210,7 +210,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + return log_error_errno(r, "Failed to add row to table: %m"); + + if (i.idle_hint) +- r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp); + else + r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) diff --git a/0946-loginctl-also-show-idle-hint-in-session-status.patch b/0946-loginctl-also-show-idle-hint-in-session-status.patch new file mode 100644 index 0000000..f69b6fa --- /dev/null +++ b/0946-loginctl-also-show-idle-hint-in-session-status.patch @@ -0,0 +1,40 @@ +From 0d3f481f791d918380a1b5587529cb8642d3e407 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Tue, 23 May 2023 18:54:30 +0800 +Subject: [PATCH] loginctl: also show idle hint in session-status + +(cherry picked from commit 82449055af97cf92466dbe132a89c9d889440c3d) + +Related: #2156786 +--- + src/login/loginctl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 1131267015..80d0a302d3 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -473,6 +473,8 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) }, + { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) }, + { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, + { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) }, + { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) }, + {} +@@ -571,6 +573,14 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + if (i.state) + printf("\t State: %s\n", i.state); + ++ if (i.idle_hint && i.idle_hint_timestamp > 0) { ++ s1 = format_timestamp_relative(since1, sizeof(since1), i.idle_hint_timestamp); ++ s2 = format_timestamp(since2, sizeof(since2), i.idle_hint_timestamp); ++ ++ printf("\t Idle: %s since %s (%s)\n", yes_no(i.idle_hint), s2, s1); ++ } else ++ printf("\t Idle: %s\n", yes_no(i.idle_hint)); ++ + if (i.scope) { + printf("\t Unit: %s\n", i.scope); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader); diff --git a/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch b/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch new file mode 100644 index 0000000..cc9bb1a --- /dev/null +++ b/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch @@ -0,0 +1,46 @@ +From a741d3b8bc23b4be1b83e393ca864983558a730c Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 23 May 2023 16:24:47 +0200 +Subject: [PATCH] core/timer: Always use inactive_exit_timestamp if it is set + +If we're doing a daemon-reload, we'll be going from TIMER_DEAD => TIMER_WAITING, +so we won't use inactive_exit_timestamp because TIMER_DEAD != UNIT_ACTIVE, even +though inactive_exit_timestamp is serialized/deserialized and will be valid after +the daemon-reload. + +This issue can lead to timers never firing as we'll always calculate the next +elapse based on the current realtime on daemon-reload, so if daemon-reload happens +often enough, the elapse interval will be moved into the future every time, which +means the timer will never trigger. + +To fix the issue, let's always use inactive_exit_timestamp if it is set, and only +fall back to the current realtime if it is not set. + +(cherry picked from commit 6546045fa0bf84737bd8b2e1e8bf7dd3941d8352) + +Resolves: #1719364 +--- + src/core/timer.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 990f05fee4..b80f6d714c 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -368,12 +368,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + + if (t->last_trigger.realtime > 0) + b = t->last_trigger.realtime; +- else { +- if (state_translation_table[t->state] == UNIT_ACTIVE) +- b = UNIT(t)->inactive_exit_timestamp.realtime; +- else +- b = ts.realtime; +- } ++ else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) ++ b = UNIT(t)->inactive_exit_timestamp.realtime; ++ else ++ b = ts.realtime; + + r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse); + if (r < 0) diff --git a/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch b/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch new file mode 100644 index 0000000..e7518ab --- /dev/null +++ b/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch @@ -0,0 +1,25 @@ +From e7c06a10a106068e5bd9f092edbfcc937954a959 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 24 May 2023 11:41:37 +0200 +Subject: [PATCH] timer: Use dual_timestamp_is_set() in one more place + +(cherry picked from commit e21f75afcd95a46261a36a2614712eff6bc119f4) + +Related: #1719364 +--- + src/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index b80f6d714c..81468d4ca6 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -366,7 +366,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + * to that. If we don't, just start from + * the activation time. */ + +- if (t->last_trigger.realtime > 0) ++ if (dual_timestamp_is_set(&t->last_trigger)) + b = t->last_trigger.realtime; + else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) + b = UNIT(t)->inactive_exit_timestamp.realtime; diff --git a/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch b/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch new file mode 100644 index 0000000..0900c1b --- /dev/null +++ b/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch @@ -0,0 +1,28 @@ +From d55687b7489127b4b6be953c54719f3219e852f6 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 13 Jul 2023 14:23:51 +0200 +Subject: [PATCH] ci: drop systemd-stable from advanced-commit-linter config + +It's sufficient enough to check only the `systemd/systemd` repo. + +Related to https://github.com/redhat-plumbers-in-action/advanced-commit-linter/issues/62 + +rhel-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 327af0467a..0fb74a9dc8 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -2,7 +2,6 @@ policy: + cherry-pick: + upstream: + - github: systemd/systemd +- - github: systemd/systemd-stable + exception: + note: + - rhel-only diff --git a/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch b/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch new file mode 100644 index 0000000..c7d466c --- /dev/null +++ b/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch @@ -0,0 +1,108 @@ +From 048c335acdaaba173574305c9b03677b3fde999f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 11 May 2023 19:21:57 +0900 +Subject: [PATCH] core/mount: escape invalid UTF8 char in dbus reply + +When What= or Options= may contain invalid UTF8 chars. + +Replaces aaf7b0e41105d7b7cf30912cdac32820f011a219 (#27541). + +(cherry picked from commit 4804da58536ab7ad46178a03f4d2da49fd8e4ba2) + +Resolves: #2158724 +--- + src/core/dbus-mount.c | 69 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c +index 3f98d3ecf0..a089b37e04 100644 +--- a/src/core/dbus-mount.c ++++ b/src/core/dbus-mount.c +@@ -9,21 +9,68 @@ + #include "mount.h" + #include "string-util.h" + #include "unit.h" ++#include "utf8.h" ++ ++static int property_get_what( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); + +-static const char *mount_get_what(const Mount *m) { + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what) +- return m->parameters_proc_self_mountinfo.what; +- if (m->from_fragment && m->parameters_fragment.what) +- return m->parameters_fragment.what; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.what; ++ else if (m->from_fragment && m->parameters_fragment.what) ++ s = m->parameters_fragment.what; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + +-static const char *mount_get_options(const Mount *m) { ++static int property_get_options( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); ++ + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options) +- return m->parameters_proc_self_mountinfo.options; +- if (m->from_fragment && m->parameters_fragment.options) +- return m->parameters_fragment.options; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.options; ++ else if (m->from_fragment && m->parameters_fragment.options) ++ s = m->parameters_fragment.options; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + + static const char *mount_get_fstype(const Mount *m) { +@@ -34,8 +81,6 @@ static const char *mount_get_fstype(const Mount *m) { + return NULL; + } + +-static BUS_DEFINE_PROPERTY_GET(property_get_what, "s", Mount, mount_get_what); +-static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Mount, mount_get_options); + static BUS_DEFINE_PROPERTY_GET(property_get_type, "s", Mount, mount_get_fstype); + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult); + diff --git a/0912-login-add-a-missing-error-check-for-session_set_lead.patch b/0951-login-add-a-missing-error-check-for-session_set_lead.patch similarity index 92% rename from 0912-login-add-a-missing-error-check-for-session_set_lead.patch rename to 0951-login-add-a-missing-error-check-for-session_set_lead.patch index 7a23c6a..3004e81 100644 --- a/0912-login-add-a-missing-error-check-for-session_set_lead.patch +++ b/0951-login-add-a-missing-error-check-for-session_set_lead.patch @@ -1,4 +1,4 @@ -From 1ac7d4d5ee3bb00a3e7d310f7b8803812940e0a4 Mon Sep 17 00:00:00 2001 +From fd6e63d9c24845c0e9f97d0929d89dbe0c4a4434 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 14 Feb 2019 10:59:13 +0900 Subject: [PATCH] login: add a missing error check for session_set_leader() @@ -10,7 +10,7 @@ This may be related to RHBZ#1663704. (cherry picked from commit fe3ab8458b9c0ead4b3e14ac25b342d8c34376fe) -Related: #2223602 +Related: #2158167 --- src/login/logind-dbus.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/0913-logind-reset-session-leader-if-we-know-for-a-fact-th.patch b/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch similarity index 93% rename from 0913-logind-reset-session-leader-if-we-know-for-a-fact-th.patch rename to 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch index b08b3b7..fe3fdb9 100644 --- a/0913-logind-reset-session-leader-if-we-know-for-a-fact-th.patch +++ b/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch @@ -1,4 +1,4 @@ -From 33c66376740d069502ae807d0fa582865cddc359 Mon Sep 17 00:00:00 2001 +From ab53c4f5c39ab8d34a3cca652de67fe31dbb776d Mon Sep 17 00:00:00 2001 From: Michal Sekletar Date: Wed, 5 Jul 2023 15:27:38 +0200 Subject: [PATCH] logind: reset session leader if we know for a fact that it is @@ -6,7 +6,7 @@ Subject: [PATCH] logind: reset session leader if we know for a fact that it is rhel-only -Related: #2223602 +Related: #2158167 --- src/login/logind-dbus.c | 3 +++ src/login/logind-session.c | 18 ++++++++++++++++++ @@ -28,7 +28,7 @@ index 5edcf4e43f..dbac406035 100644 user_save(session->user); } diff --git a/src/login/logind-session.c b/src/login/logind-session.c -index 916202a65a..c143202d0b 100644 +index fabf680b61..4edc4b9b88 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -179,6 +179,23 @@ int session_set_leader(Session *s, pid_t pid) { @@ -55,7 +55,7 @@ index 916202a65a..c143202d0b 100644 static void session_save_devices(Session *s, FILE *f) { SessionDevice *sd; Iterator i; -@@ -1096,6 +1113,7 @@ static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, +@@ -1092,6 +1109,7 @@ static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, /* EOF on the FIFO means the session died abnormally. */ session_remove_fifo(s); diff --git a/0953-test-login-skip-consistency-checks-when-logind-is-no.patch b/0953-test-login-skip-consistency-checks-when-logind-is-no.patch new file mode 100644 index 0000000..b7c0b43 --- /dev/null +++ b/0953-test-login-skip-consistency-checks-when-logind-is-no.patch @@ -0,0 +1,170 @@ +From f80320d15ba6815f0b385e4b8f86f3293fed66ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 16 Dec 2020 15:56:44 +0100 +Subject: [PATCH] test-login: skip consistency checks when logind is not active +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are two ways in swich sd_login_* functions acquire data: +some are derived from the cgroup path, but others use the data serialized +by logind. + +When the tests are executed under Fedora's mock, without systemd-spawn +but instead in a traditional chroot, test-login gets confused: +the "outside" cgroup path is visible, so sd_pid_get_unit() and +sd_pid_get_session() work, but sd_session_is_active() and other functions +that need logind data fail. + +Such a buildroot setup is fairly bad, but it can be encountered in the wild, so +let's just skip the tests in that case. + +/* Information printed is from the live system */ +sd_pid_get_unit(0, …) → "session-237.scope" +sd_pid_get_user_unit(0, …) → "n/a" +sd_pid_get_slice(0, …) → "user-1000.slice" +sd_pid_get_session(0, …) → "237" +sd_pid_get_owner_uid(0, …) → 1000 +sd_pid_get_cgroup(0, …) → "/user.slice/user-1000.slice/session-237.scope" +sd_uid_get_display(1000, …) → "(null)" +sd_uid_get_sessions(1000, …) → [0] "" +sd_uid_get_seats(1000, …) → [0] "" +Assertion 'r >= 0' failed at src/libsystemd/sd-login/test-login.c:104, function test_login(). Aborting. + +(cherry picked from commit ac5644635dba54ce5eb0ff394fc0bc772a984849) + +Resolves: #2223582 +--- + src/libsystemd/sd-login/test-login.c | 98 +++++++++++++++------------- + 1 file changed, 52 insertions(+), 46 deletions(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index d24a04ccc8..5a64aef868 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -115,65 +115,71 @@ static void test_login(void) { + + if (session) { + r = sd_session_is_active(session); +- assert_se(r >= 0); +- log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); ++ if (r == -ENXIO) ++ log_notice("sd_session_is_active() failed with ENXIO, it seems logind is not running."); ++ else { ++ /* All those tests will fail with ENXIO, so let's skip them. */ + +- r = sd_session_is_remote(session); +- assert_se(r >= 0); +- log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); ++ assert_se(r >= 0); ++ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); + +- r = sd_session_get_state(session, &state); +- assert_se(r == 0); +- log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); ++ r = sd_session_is_remote(session); ++ assert_se(r >= 0); ++ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); + +- assert_se(sd_session_get_uid(session, &u) >= 0); +- log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); +- assert_se(u == u2); ++ r = sd_session_get_state(session, &state); ++ assert_se(r == 0); ++ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); + +- assert_se(sd_session_get_type(session, &type) >= 0); +- log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); ++ assert_se(sd_session_get_uid(session, &u) >= 0); ++ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); ++ assert_se(u == u2); + +- assert_se(sd_session_get_class(session, &class) >= 0); +- log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); ++ assert_se(sd_session_get_type(session, &type) >= 0); ++ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); + +- r = sd_session_get_display(session, &display); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); ++ assert_se(sd_session_get_class(session, &class) >= 0); ++ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); + +- r = sd_session_get_remote_user(session, &remote_user); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", +- session, strna(remote_user)); ++ r = sd_session_get_display(session, &display); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); + +- r = sd_session_get_remote_host(session, &remote_host); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", +- session, strna(remote_host)); ++ r = sd_session_get_remote_user(session, &remote_user); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", ++ session, strna(remote_user)); + +- r = sd_session_get_seat(session, &seat); +- if (r >= 0) { +- assert_se(seat); ++ r = sd_session_get_remote_host(session, &remote_host); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", ++ session, strna(remote_host)); + +- log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); ++ r = sd_session_get_seat(session, &seat); ++ if (r >= 0) { ++ assert_se(seat); + +- r = sd_seat_can_multi_session(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); ++ log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); + +- r = sd_seat_can_tty(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); ++ r = sd_seat_can_multi_session(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); + +- r = sd_seat_can_graphical(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); +- } else { +- log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); +- assert_se(r == -ENODATA); +- } ++ r = sd_seat_can_tty(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); + +- assert_se(sd_uid_get_state(u, &state2) == 0); +- log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ r = sd_seat_can_graphical(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); ++ } else { ++ log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); ++ assert_se(r == -ENODATA); ++ } ++ ++ assert_se(sd_uid_get_state(u, &state2) == 0); ++ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ } + } + + if (seat) { +@@ -214,7 +220,7 @@ static void test_login(void) { + assert_se(sd_get_seats(NULL) == r); + + r = sd_seat_get_active(NULL, &t, NULL); +- assert_se(IN_SET(r, 0, -ENODATA)); ++ assert_se(IN_SET(r, 0, -ENODATA, -ENXIO)); + log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t)); + free(t); + diff --git a/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch b/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch new file mode 100644 index 0000000..aabdbcd --- /dev/null +++ b/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch @@ -0,0 +1,91 @@ +From 7bbad13204b3c0870caa80e738d5d5ca39e956c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 25 Sep 2018 11:10:12 +0200 +Subject: [PATCH] sd-event: remove dead code and use _cleanup_ + +CID #1393250. + +(cherry picked from commit 8c75fe1765341b538ddded29be6f98e1619f1996) + +Related: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 30 +++++++++--------------------- + 1 file changed, 9 insertions(+), 21 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 549103bc6f..5e22190366 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1129,6 +1129,7 @@ static void source_free(sd_event_source *s) { + free(s->description); + free(s); + } ++DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free); + + static int source_set_pending(sd_event_source *s, bool b) { + int r; +@@ -1993,11 +1994,10 @@ _public_ int sd_event_add_inotify( + sd_event_inotify_handler_t callback, + void *userdata) { + +- bool rm_inotify = false, rm_inode = false; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; + _cleanup_close_ int fd = -1; +- sd_event_source *s; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + +@@ -2035,13 +2035,13 @@ _public_ int sd_event_add_inotify( + /* Allocate an inotify object for this priority, and an inode object within it */ + r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data); + if (r < 0) +- goto fail; +- rm_inotify = r > 0; ++ return r; + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); +- if (r < 0) +- goto fail; +- rm_inode = r > 0; ++ if (r < 0) { ++ event_free_inotify_data(e, inotify_data); ++ return r; ++ } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ +@@ -2054,30 +2054,18 @@ _public_ int sd_event_add_inotify( + LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s); + s->inotify.inode_data = inode_data; + +- rm_inode = rm_inotify = false; +- + /* Actually realize the watch now */ + r = inode_data_realize_watch(e, inode_data); + if (r < 0) +- goto fail; ++ return r; + + (void) sd_event_source_set_description(s, path); + + if (ret) + *ret = s; ++ TAKE_PTR(s); + + return 0; +- +-fail: +- source_free(s); +- +- if (rm_inode) +- event_free_inode_data(e, inode_data); +- +- if (rm_inotify) +- event_free_inotify_data(e, inotify_data); +- +- return r; + } + + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { diff --git a/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch b/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch new file mode 100644 index 0000000..6fb60e2 --- /dev/null +++ b/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch @@ -0,0 +1,100 @@ +From 4436c767d45c6568cbdb7aa73e5efba6d0f31f1f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:11:38 +0100 +Subject: [PATCH] sd-event: don't destroy inotify data structures from inotify + event handler + +This fixes a bad memory access when we destroy an inotify source handler +from the handler itself, and thus destroy the associated inotify_data +structures. + +Fixes: #20177 +(cherry picked from commit 53baf2efa420cab6c4b1904c9a0c46a0c4ec80a1) + +Resolves: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 45 +++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 5e22190366..01a97a4801 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -263,6 +263,11 @@ struct inotify_data { + * the events locally if they can't be coalesced). */ + unsigned n_pending; + ++ /* If this counter is non-zero, don't GC the inotify data object even if not used to watch any inode ++ * anymore. This is useful to pin the object for a bit longer, after the last event source needing it ++ * is gone. */ ++ unsigned n_busy; ++ + /* A linked list of all inotify objects with data already read, that still need processing. We keep this list + * to make it efficient to figure out what inotify objects to process data on next. */ + LIST_FIELDS(struct inotify_data, buffered); +@@ -1845,6 +1850,29 @@ static void event_free_inode_data( + free(d); + } + ++static void event_gc_inotify_data( ++ sd_event *e, ++ struct inotify_data *d) { ++ ++ assert(e); ++ ++ /* GCs the inotify data object if we don't need it anymore. That's the case if we don't want to watch ++ * any inode with it anymore, which in turn happens if no event source of this priority is interested ++ * in any inode any longer. That said, we maintain an extra busy counter: if non-zero we'll delay GC ++ * (under the expectation that the GC is called again once the counter is decremented). */ ++ ++ if (!d) ++ return; ++ ++ if (!hashmap_isempty(d->inodes)) ++ return; ++ ++ if (d->n_busy > 0) ++ return; ++ ++ event_free_inotify_data(e, d); ++} ++ + static void event_gc_inode_data( + sd_event *e, + struct inode_data *d) { +@@ -1862,8 +1890,7 @@ static void event_gc_inode_data( + inotify_data = d->inotify_data; + event_free_inode_data(e, d); + +- if (inotify_data && hashmap_isempty(inotify_data->inodes)) +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + } + + static int event_make_inode_data( +@@ -3447,13 +3474,23 @@ static int source_dispatch(sd_event_source *s) { + sz = offsetof(struct inotify_event, name) + d->buffer.ev.len; + assert(d->buffer_filled >= sz); + ++ /* If the inotify callback destroys the event source then this likely means we don't need to ++ * watch the inode anymore, and thus also won't need the inotify object anymore. But if we'd ++ * free it immediately, then we couldn't drop the event from the inotify event queue without ++ * memory corruption anymore, as below. Hence, let's not free it immediately, but mark it ++ * "busy" with a counter (which will ensure it's not GC'ed away prematurely). Let's then ++ * explicitly GC it after we are done dropping the inotify event from the buffer. */ ++ d->n_busy++; + r = s->inotify.callback(s, &d->buffer.ev, s->userdata); ++ d->n_busy--; + +- /* When no event is pending anymore on this inotify object, then let's drop the event from the +- * buffer. */ ++ /* When no event is pending anymore on this inotify object, then let's drop the event from ++ * the inotify event queue buffer. */ + if (d->n_pending == 0) + event_inotify_data_drop(e, d, sz); + ++ /* Now we don't want to access 'd' anymore, it's OK to GC now. */ ++ event_gc_inotify_data(e, d); + break; + } + diff --git a/0956-sd-event-add-sd_event_add_inotify_fd-call.patch b/0956-sd-event-add-sd_event_add_inotify_fd-call.patch new file mode 100644 index 0000000..726c029 --- /dev/null +++ b/0956-sd-event-add-sd_event_add_inotify_fd-call.patch @@ -0,0 +1,232 @@ +From a78186fbbc05637ef9678b20c630597f2e5d6270 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:10:58 +0100 +Subject: [PATCH] sd-event: add sd_event_add_inotify_fd() call + +sd_event_add_inotify_fd() is like sd_event_add_inotify(), but takes an +fd to an inode instead of a path, and is hence a ton nicer. + +(cherry picked from commit e67d738a8771c220a2e1ee81d5499a90589dd15d) + +Related: #2211358 +--- + man/rules/meson.build | 4 +- + man/sd_event_add_inotify.xml | 16 +++++++ + src/libsystemd/libsystemd.sym | 1 + + src/libsystemd/sd-event/sd-event.c | 76 +++++++++++++++++++++++------- + src/systemd/sd-event.h | 1 + + 5 files changed, 81 insertions(+), 17 deletions(-) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 05eb0a1604..431a1cf269 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -272,7 +272,9 @@ manpages = [ + ''], + ['sd_event_add_inotify', + '3', +- ['sd_event_inotify_handler_t', 'sd_event_source_get_inotify_mask'], ++ ['sd_event_add_inotify_fd', ++ 'sd_event_inotify_handler_t', ++ 'sd_event_source_get_inotify_mask'], + ''], + ['sd_event_add_io', + '3', +diff --git a/man/sd_event_add_inotify.xml b/man/sd_event_add_inotify.xml +index 605863c356..17415bbc17 100644 +--- a/man/sd_event_add_inotify.xml ++++ b/man/sd_event_add_inotify.xml +@@ -18,6 +18,7 @@ + + + sd_event_add_inotify ++ sd_event_add_inotify_fd + sd_event_source_get_inotify_mask + sd_event_inotify_handler_t + +@@ -47,6 +48,16 @@ + void *userdata + + ++ ++ int sd_event_add_inotify_fd ++ sd_event *event ++ sd_event_source **source ++ int fd ++ uint32_t mask ++ sd_event_inotify_handler_t handler ++ void *userdata ++ ++ + + int sd_event_source_get_inotify_mask + sd_event_source *source +@@ -72,6 +83,11 @@ + inotify7 for + further information. + ++ sd_event_add_inotify_fd() is identical to ++ sd_event_add_inotify(), except that it takes a file descriptor to an inode (possibly ++ an O_PATH one, but any other will do too) instead of a path in the file ++ system. ++ + If multiple event sources are installed for the same inode the backing inotify watch descriptor is + automatically shared. The mask parameter may contain any flag defined by the inotify API, with the exception of + IN_MASK_ADD. +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 449918093c..dc37472b18 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -593,5 +593,6 @@ global: + + LIBSYSTEMD_250 { + global: ++ sd_event_add_inotify_fd; + sd_event_source_set_ratelimit_expire_callback; + } LIBSYSTEMD_248; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 01a97a4801..9247087c41 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2013,25 +2013,25 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { + return 1; + } + +-_public_ int sd_event_add_inotify( ++static int event_add_inotify_fd_internal( + sd_event *e, + sd_event_source **ret, +- const char *path, ++ int fd, ++ bool donate, + uint32_t mask, + sd_event_inotify_handler_t callback, + void *userdata) { + ++ _cleanup_close_ int donated_fd = donate ? fd : -1; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; +- _cleanup_close_ int fd = -1; +- _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + + assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); +- assert_return(path, -EINVAL); +- assert_return(callback, -EINVAL); ++ assert_return(fd >= 0, -EBADF); + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(!event_pid_changed(e), -ECHILD); + +@@ -2041,12 +2041,6 @@ _public_ int sd_event_add_inotify( + if (mask & IN_MASK_ADD) + return -EINVAL; + +- fd = open(path, O_PATH|O_CLOEXEC| +- (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| +- (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); +- if (fd < 0) +- return -errno; +- + if (fstat(fd, &st) < 0) + return -errno; + +@@ -2066,14 +2060,24 @@ _public_ int sd_event_add_inotify( + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); + if (r < 0) { +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + return r; + } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ + if (inode_data->fd < 0) { +- inode_data->fd = TAKE_FD(fd); ++ if (donated_fd >= 0) ++ inode_data->fd = TAKE_FD(donated_fd); ++ else { ++ inode_data->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); ++ if (inode_data->fd < 0) { ++ r = -errno; ++ event_gc_inode_data(e, inode_data); ++ return r; ++ } ++ } ++ + LIST_PREPEND(to_close, e->inode_data_to_close, inode_data); + } + +@@ -2086,8 +2090,6 @@ _public_ int sd_event_add_inotify( + if (r < 0) + return r; + +- (void) sd_event_source_set_description(s, path); +- + if (ret) + *ret = s; + TAKE_PTR(s); +@@ -2095,6 +2097,48 @@ _public_ int sd_event_add_inotify( + return 0; + } + ++_public_ int sd_event_add_inotify_fd( ++ sd_event *e, ++ sd_event_source **ret, ++ int fd, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ return event_add_inotify_fd_internal(e, ret, fd, /* donate= */ false, mask, callback, userdata); ++} ++ ++_public_ int sd_event_add_inotify( ++ sd_event *e, ++ sd_event_source **ret, ++ const char *path, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ sd_event_source *s; ++ int fd, r; ++ ++ assert_return(path, -EINVAL); ++ ++ fd = open(path, O_PATH|O_CLOEXEC| ++ (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| ++ (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); ++ if (fd < 0) ++ return -errno; ++ ++ r = event_add_inotify_fd_internal(e, &s, fd, /* donate= */ true, mask, callback, userdata); ++ if (r < 0) ++ return r; ++ ++ (void) sd_event_source_set_description(s, path); ++ ++ if (ret) ++ *ret = s; ++ ++ return r; ++} ++ + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { + + if (!s) +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index 960bea1ac4..48b053c127 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -91,6 +91,7 @@ int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock + int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); + int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); + int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); ++int sd_event_add_inotify_fd(sd_event *e, sd_event_source **s, int fd, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); + int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); diff --git a/0957-test-add-test-case-for-self-destroy-inotify-handler.patch b/0957-test-add-test-case-for-self-destroy-inotify-handler.patch new file mode 100644 index 0000000..c2e2cb3 --- /dev/null +++ b/0957-test-add-test-case-for-self-destroy-inotify-handler.patch @@ -0,0 +1,65 @@ +From 2fcb71007e5137e1be4a16fb24783ff329313ebf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:15:43 +0100 +Subject: [PATCH] test: add test case for self-destroy inotify handler + +(cherry picked from commit 035daf73fbfa05e5abf049bd9385fc0994ab5672) + +Related: #2211358 +--- + src/libsystemd/sd-event/test-event.c | 36 ++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index 9135b22839..df3de1bfb0 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -588,6 +588,40 @@ static void test_ratelimit(void) { + assert_se(expired == 0); + } + ++static int inotify_self_destroy_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) { ++ sd_event_source **p = userdata; ++ ++ assert_se(ev); ++ assert_se(p); ++ assert_se(*p == s); ++ ++ assert_se(FLAGS_SET(ev->mask, IN_ATTRIB)); ++ ++ assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0); ++ ++ *p = sd_event_source_unref(*p); /* here's what we actually intend to test: we destroy the event ++ * source from inside the event source handler */ ++ return 1; ++} ++ ++static void test_inotify_self_destroy(void) { ++ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; ++ _cleanup_(sd_event_unrefp) sd_event *e = NULL; ++ char path[] = "/tmp/inotifyXXXXXX"; ++ _cleanup_close_ int fd = -1; ++ ++ /* Tests that destroying an inotify event source from its own handler is safe */ ++ ++ assert_se(sd_event_default(&e) >= 0); ++ ++ fd = mkostemp_safe(path); ++ assert_se(fd >= 0); ++ assert_se(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s) >= 0); ++ fd = safe_close(fd); ++ assert_se(unlink(path) >= 0); /* This will trigger IN_ATTRIB because link count goes to zero */ ++ assert_se(sd_event_loop(e) >= 0); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -602,5 +636,7 @@ int main(int argc, char *argv[]) { + + test_ratelimit(); + ++ test_inotify_self_destroy(); ++ + return 0; + } diff --git a/0958-doc-add-downstream-CONTRIBUTING-document.patch b/0958-doc-add-downstream-CONTRIBUTING-document.patch new file mode 100644 index 0000000..c221180 --- /dev/null +++ b/0958-doc-add-downstream-CONTRIBUTING-document.patch @@ -0,0 +1,86 @@ +From 322ef6cb5fe3c293c6b9a37fe2e58491e9a5100b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 4 Aug 2023 13:09:46 +0200 +Subject: [PATCH] doc: add downstream CONTRIBUTING document + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) + create mode 100644 CONTRIBUTING.md + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +new file mode 100644 +index 0000000000..361366d899 +--- /dev/null ++++ b/CONTRIBUTING.md +@@ -0,0 +1,67 @@ ++# Contributing ++ ++Welcome to systemd source-git for CentOS Stream and RHEL. When contributing, please follow the guide below. ++ ++## Workflow ++ ++```mermaid ++flowchart LR ++ A(Issue) --> B{is fixed\nupstream} ++ B -->|YES| C(backport\nupstream patch) ++ B -->|NO| D(upstream\nsubmit issue or PR) ++ D --> E{accepted\nand fixed} ++ E -->|YES| C ++ E -->|NO| F(rhel-only patch) --> G ++ C --> G(submit PR) ++``` ++ ++## Filing issues ++ ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++ ++GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). ++ ++## Posting Pull Requests ++ ++Every Pull Request has to comply with the following rules: ++ ++- Each commit has to reference [upstream](https://github.com/systemd/systemd) commit. ++- Each commit has to reference the approved issue/tracker. ++- Pull requests have to pass mandatory CI validation and testing ++- Pull requests have to be approved by at least one systemd downstream maintainer ++ ++### Upstream reference ++ ++When doing a back-port of an upstream commit, always use `cherry-pick -x `. Consider proposing a change upstream first when an upstream commit doesn't exist. ++If the change isn't upstream relevant or accepted by upstream, mark the commit with the `rhel-only` string. ++ ++```md ++doc: Fix TYPO ++ ++rhel-only ++ ++Resolves: RHEL-678 ++``` ++ ++### Issue reference ++ ++Each commit has to reference the relevant approved systemd issue (see: [Filling issues section](#filing-issues)). For referencing issues, we use the following keywords: ++ ++- **Resolves** for commits that directly resolve issues described in a referenced tracker ++- **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. ++- **Reverts** for commits that reverts previously merged commit ++ ++When referencing issues, use following structure: `: `. See the example below: ++ ++```md ++doc: Fix TYPO ++ ++(cherry picked from commit c5afbac31bb33e7b1f4d59b253425af991a630a4) ++ ++Resolves: RHEL-678 ++``` ++ ++### Validation and testing ++ ++Each Pull Request has to pass all enabled tests that are automatically run using GitHub Actions, CentOS Stream CI, and others. ++If CI failure is unrelated to the change introduced in Pull Request, the downstream maintainer will set the `ci-waived` label and explain why CI was waived. diff --git a/0959-doc-use-link-with-prefilled-Jira-issue.patch b/0959-doc-use-link-with-prefilled-Jira-issue.patch new file mode 100644 index 0000000..d93e59e --- /dev/null +++ b/0959-doc-use-link-with-prefilled-Jira-issue.patch @@ -0,0 +1,25 @@ +From b50b19af7889a2d44e904fcb327b09130c9c96e7 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 8 Aug 2023 13:12:03 +0200 +Subject: [PATCH] doc: use link with prefilled Jira issue + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 361366d899..1de2b88995 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + diff --git a/0960-docs-link-downstream-CONTRIBUTING-in-README.patch b/0960-docs-link-downstream-CONTRIBUTING-in-README.patch new file mode 100644 index 0000000..0d5de6b --- /dev/null +++ b/0960-docs-link-downstream-CONTRIBUTING-in-README.patch @@ -0,0 +1,52 @@ +From 380f7af4fb00d692132b38999813fd9023e14c81 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 10 Aug 2023 15:25:22 +0200 +Subject: [PATCH] docs: link downstream CONTRIBUTING in README + +This should increase the visibility of the downstream CONTRIBUTING. + +Also fix some wording and update links. + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 4 ++-- + README.md | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 1de2b88995..bd17067be2 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). ++When you find an issue with systemd used in **CentOS Stream** or **RHEL**, please file an issue in Red Hat [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515&priority=10300). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + +@@ -51,7 +51,7 @@ Each commit has to reference the relevant approved systemd issue (see: [Filling + - **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. + - **Reverts** for commits that reverts previously merged commit + +-When referencing issues, use following structure: `: `. See the example below: ++When referencing issues, use the following structure: `: `. See the example below: + + ```md + doc: Fix TYPO +diff --git a/README.md b/README.md +index a57566834c..2e02350299 100644 +--- a/README.md ++++ b/README.md +@@ -17,7 +17,7 @@ Consult our [NEWS file](../master/NEWS) for information about what's new in the + + Please see the [HACKING file](../master/doc/HACKING) for information how to hack on systemd and test your modifications. + +-Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. ++Please see our [Contribution Guidelines](CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. + + When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/doc/CODING_STYLE). + diff --git a/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch b/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch new file mode 100644 index 0000000..a346838 --- /dev/null +++ b/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch @@ -0,0 +1,47 @@ +From e257d900b45df7db779fd34f01b251d4054f3685 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:49:51 +0000 +Subject: [PATCH] unit drop-in: Fix ordering of special type.d drop-ins + +(cherry picked from commit e6627f2392cde12e21c40a7cfa96578c648c1f33) + +Related: #2156620 +--- + src/shared/dropin.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index 11ed4c7184..927107c508 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -242,6 +242,10 @@ int unit_file_find_dropin_paths( + + assert(ret); + ++ SET_FOREACH(name, names, i) ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); ++ + /* All the names in the unit are of the same type so just grab one. */ + name = (char*) set_first(names); + if (name) { +@@ -253,7 +257,7 @@ int unit_file_find_dropin_paths( + "Failed to to derive unit type from unit name: %s", + name); + +- /* Special top level drop in for ".". Add this first as it's the most generic ++ /* Special top level drop in for ".". Add this last as it's the most generic + * and should be able to be overridden by more specific drop-ins. */ + STRV_FOREACH(p, lookup_path) + (void) unit_file_find_dirs(original_root, +@@ -264,10 +268,6 @@ int unit_file_find_dropin_paths( + &dirs); + } + +- SET_FOREACH(name, names, i) +- STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); +- + if (strv_isempty(dirs)) { + *ret = NULL; + return 0; diff --git a/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch b/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch new file mode 100644 index 0000000..1fbf0c3 --- /dev/null +++ b/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch @@ -0,0 +1,57 @@ +From 471f790115b2b0a56328cbf14a6e0f51c1176b62 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:36:49 +0000 +Subject: [PATCH] Add failing test to show service.d global drop-in does not + get overridden by more specific dropins + +(cherry picked from commit f5dd6e50a781b83bc6b1d8e018783661142aabd0) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5419169f7b..a9d1ef0a10 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -118,6 +118,31 @@ EOF + clear_services a b c + } + ++test_hierarchical_dropins () { ++ echo "Testing hierarchical dropins..." ++ echo "*** test service.d/ top level drop-in" ++ create_services a-b-c ++ check_ko a-b-c ExecCondition "/bin/echo service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Service] ++ExecCondition=/bin/echo $dropin ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ done ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ rm -rf /usr/lib/systemd/system/$dropin ++ done ++ ++ clear_services a-b-c ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -303,6 +328,7 @@ test_invalid_dropins () { + } + + test_basic_dropins ++test_hierarchical_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0963-test-set-indentation-to-4-spaces.patch b/0963-test-set-indentation-to-4-spaces.patch new file mode 100644 index 0000000..30a5591 --- /dev/null +++ b/0963-test-set-indentation-to-4-spaces.patch @@ -0,0 +1,522 @@ +From 3681938e3aa5d3580038011b4579ac39612df23e Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 13 Apr 2023 14:48:00 +0200 +Subject: [PATCH] test: set indentation to 4 spaces + +This is what upstream commit cc5549ca12616376a4e4ef04fd4e2fb53d6d098c +has done, but just for a single shell file. + +RHEL-only + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 448 ++++++++++++++--------------- + 1 file changed, 224 insertions(+), 224 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a9d1ef0a10..64d8a98fc7 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,103 +4,103 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ systemctl stop $1.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} + } + + clear_services () { +- for u in $*; do +- _clear_service $u +- done +- systemctl daemon-reload ++ for u in $*; do ++ _clear_service $u ++ done ++ systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ clear_services $1 + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/$1.service</usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/wants-b.conf</usr/lib/systemd/system/a.service.d/wants-b.conf< +Date: Sat, 21 Mar 2020 16:30:27 +0100 +Subject: [PATCH] test/TEST-15: remove all created unit files + +We would miss anything created under a template instance. + +(cherry picked from commit 4e2ac45a83e5495a5c1d3ecac62a054e0cef7746) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 64d8a98fc7..30f1e84954 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -8,6 +8,12 @@ _clear_service () { + rm -f /{etc,run,usr/lib}/systemd/system/$1.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ if [[ $1 == *@ ]]; then ++ systemctl stop $1*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ fi + } + + clear_services () { diff --git a/0965-test-use-quotes-where-necessary.patch b/0965-test-use-quotes-where-necessary.patch new file mode 100644 index 0000000..03bf462 --- /dev/null +++ b/0965-test-use-quotes-where-necessary.patch @@ -0,0 +1,95 @@ +From 209b8c92f0c44644d0476349b4a65f4b9ad942de Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 9 Apr 2021 19:49:32 +0200 +Subject: [PATCH] test: use quotes where necessary + +to avoid possible word splitting. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit 38825267983a439f2cf8375463b1edc9ca2d3323) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 30f1e84954..a197989f72 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,51 +4,53 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} +- if [[ $1 == *@ ]]; then +- systemctl stop $1*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} ++ if [[ $SERVICE_NAME == *@ ]]; then ++ systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} + fi + } + + clear_services () { +- for u in $*; do +- _clear_service $u ++ for u in "$@"; do ++ _clear_service "$u" + done + systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ local SERVICE_NAME="${1:?create_service: missing argument}" ++ clear_services "$SERVICE_NAME" + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/"$SERVICE_NAME".service < +Date: Wed, 4 May 2022 08:24:06 +0200 +Subject: [PATCH] tree-wide: drop manually-crafted message for missing + variables + +Bash will generate a very nice message for us: +/tmp/ff.sh: line 1: SOMEVAR: parameter null or not set + +Let's save some keystrokes by not replacing this with our own inferior +messages. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit d7ff52403902900b61f644f87b5222822fd4a69b) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a197989f72..c2c96d9797 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,7 +4,7 @@ set -e + set -x + + _clear_service () { +- local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service + rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +@@ -25,7 +25,7 @@ clear_services () { + } + + create_service () { +- local SERVICE_NAME="${1:?create_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + clear_services "$SERVICE_NAME" + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Fri, 14 Oct 2022 14:40:24 +0200 +Subject: [PATCH] manager: reformat boolean expression in unit_is_pristine() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not not IN_SET(…) is just too much for my poor brain. Let's invert +the expression to make it easier to undertand. + +(cherry picked from commit b146a7345b69de16e88347acadb3783ffeeaad9d) + +Related: #2156620 +--- + src/core/unit.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 9be2a0c326..78666e73bf 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4848,12 +4848,12 @@ bool unit_is_pristine(Unit *u) { + * are marked UNIT_LOADED even though nothing was actually + * loaded, as those unit types don't require a file on disk. */ + +- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) || +- u->fragment_path || +- u->source_path || +- !strv_isempty(u->dropin_paths) || +- u->job || +- u->merged_into); ++ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && ++ !u->fragment_path && ++ !u->source_path && ++ strv_isempty(u->dropin_paths) && ++ !u->job && ++ !u->merged_into; + } + + pid_t unit_control_pid(Unit *u) { diff --git a/0968-manager-allow-transient-units-to-have-drop-ins.patch b/0968-manager-allow-transient-units-to-have-drop-ins.patch new file mode 100644 index 0000000..c6826d1 --- /dev/null +++ b/0968-manager-allow-transient-units-to-have-drop-ins.patch @@ -0,0 +1,88 @@ +From fa8ed66b5ff48e0d8e02cfae28e90e65c70e52e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Oct 2022 15:02:20 +0200 +Subject: [PATCH] manager: allow transient units to have drop-ins + +In https://github.com/containers/podman/issues/16107, starting of a transient +slice unit fails because there's a "global" drop-in +/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by +systemd-oomd-defaults package to install some default oomd policy). This means +that the unit_is_pristine() check fails and starting of the unit is forbidden. + +It seems pretty clear to me that dropins at any other level then the unit +should be ignored in this check: we now have multiple layers of drop-ins +(for each level of the cgroup path, and also "global" ones for a specific +unit type). If we install a "global" drop-in, we wouldn't be able to start +any transient units of that type, which seems undesired. + +In principle we could reject dropins at the unit level, but I don't think that +is useful. The whole reason for drop-ins is that they are "add ons", and there +isn't any particular reason to disallow them for transient units. It would also +make things harder to implement and describe: one place for drop-ins is good, +but another is bad. (And as a corner case: for instanciated units, a drop-in +in the template would be acceptable, but a instance-specific drop-in bad?) + +Thus, $subject. + +While at it, adjust the message. All the conditions in unit_is_pristine() +essentially mean that it wasn't loaded (e.g. it might be in an error state), +and that it doesn't have a fragment path (now that drop-ins are acceptable). +If there's a job for it, it necessarilly must have been loaded. If it is +merged into another unit, it also was loaded and found to be an alias. +Based on the discussion in the bugs, it seems that the current message +is far from obvious ;) + +Fixes https://github.com/containers/podman/issues/16107, +https://bugzilla.redhat.com/show_bug.cgi?id=2133792. + +(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb) + +Resolves: #2156620 +--- + src/core/dbus-manager.c | 3 ++- + src/core/unit.c | 14 ++++++++------ + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 8a41eda4a6..ea2f3e7f59 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -892,7 +892,8 @@ static int transient_unit_from_message( + return r; + + if (!unit_is_pristine(u)) +- return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, ++ "Unit %s was already loaded or has a fragment file.", name); + + /* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +diff --git a/src/core/unit.c b/src/core/unit.c +index 78666e73bf..76fb9f8075 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4842,16 +4842,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) { + bool unit_is_pristine(Unit *u) { + assert(u); + +- /* Check if the unit already exists or is already around, +- * in a number of different ways. Note that to cater for unit +- * types such as slice, we are generally fine with units that +- * are marked UNIT_LOADED even though nothing was actually +- * loaded, as those unit types don't require a file on disk. */ ++ /* Check if the unit already exists or is already around, in a number of different ways. Note that to ++ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED ++ * even though nothing was actually loaded, as those unit types don't require a file on disk. ++ * ++ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units ++ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service: ++ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf. ++ */ + + return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && + !u->fragment_path && + !u->source_path && +- strv_isempty(u->dropin_paths) && + !u->job && + !u->merged_into; + } diff --git a/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch b/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch new file mode 100644 index 0000000..79f29d0 --- /dev/null +++ b/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch @@ -0,0 +1,135 @@ +From 8a85dd4af8e4948299b4c84df65c789999024d5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 12:42:35 +0200 +Subject: [PATCH] TEST-15: allow helper functions to accept other unit types + +clear_services() is renamed to clear_units() and now takes a full +unit name including the suffix as an argument. + +_clear_service() is renamed to clear_unit() and changed likewise. +create_service() didn't have the same underscore prefix, and I don't think +it's useful or needed for a local function, so it is removed. + +No functional change. + +(cherry picked from commit 5731e1378ad6256e34f3da33ee993343f025c075) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index c2c96d9797..bcd351360d 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -3,30 +3,32 @@ + set -e + set -x + +-_clear_service () { +- local SERVICE_NAME="${1:?}" +- systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} +- if [[ $SERVICE_NAME == *@ ]]; then +- systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} ++clear_unit () { ++ local UNIT_NAME="${1:?}" ++ systemctl stop "$UNIT_NAME" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".{wants,requires} ++ if [[ $UNIT_NAME == *@ ]]; then ++ local base="${UNIT_NAME%@*}" ++ local suffix="${UNIT_NAME##*.}" ++ systemctl stop "$base@"*."$suffix" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".{wants,requires} + fi + } + +-clear_services () { ++clear_units () { + for u in "$@"; do +- _clear_service "$u" ++ clear_unit "$u" + done + systemctl daemon-reload + } + + create_service () { + local SERVICE_NAME="${1:?}" +- clear_services "$SERVICE_NAME" ++ clear_units "${SERVICE_NAME}".service + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Sun, 16 Oct 2022 12:54:34 +0200 +Subject: [PATCH] TEST-15: also test hierarchical drop-ins for slices + +Slices are worth testing too, because they don't need a fragment path so they +behave slightly differently than service units. I'm making this a separate +patch from the actual tests that I wanted to add later because it's complex +enough on its own. + +(cherry picked from commit f80c874af376052b6b81f47cbbc43d7fecd98cd6) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 37 +++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index bcd351360d..d46946fd77 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -128,8 +128,8 @@ EOF + clear_units {a,b,c}.service + } + +-test_hierarchical_dropins () { +- echo "Testing hierarchical dropins..." ++test_hierarchical_service_dropins () { ++ echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c + check_ko a-b-c ExecCondition "/bin/echo service.d" +@@ -153,6 +153,36 @@ ExecCondition=/bin/echo $dropin + clear_units a-b-c.service + } + ++test_hierarchical_slice_dropins () { ++ echo "Testing hierarchical slice dropins..." ++ echo "*** test slice.d/ top level drop-in" ++ # Slice units don't even need a fragment, so we test the defaults here ++ check_ok a-b-c.slice Description "a-b-c.slice" ++ check_ok a-b-c.slice MemoryMax "infinity" ++ ++ # Test drop-ins ++ for dropin in slice.d a-.slice.d a-b-.slice.d a-b-c.slice.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Slice] ++MemoryMax=1000000000 ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ rm /usr/lib/systemd/system/$dropin/override.conf ++ done ++ ++ # Test unit with a fragment ++ echo " ++[Slice] ++MemoryMax=1000000001 ++ " >/usr/lib/systemd/system/a-b-c.slice ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000001" ++ ++ clear_units a-b-c.slice ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -338,7 +368,8 @@ test_invalid_dropins () { + } + + test_basic_dropins +-test_hierarchical_dropins ++test_hierarchical_service_dropins ++test_hierarchical_slice_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch b/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch new file mode 100644 index 0000000..4d892e4 --- /dev/null +++ b/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch @@ -0,0 +1,109 @@ +From c4db01d0c3e1ff05286261971ba39839cc91c21a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 14:02:45 +0200 +Subject: [PATCH] TEST-15: add test for transient units with drop-ins + +We want to test four things: +- that the transient units are successfully started when drop-ins exist +- that the transient setings override the defaults +- the drop-ins override the transient settings (the same as for a normal unit) +- that things are the same before and after a reload + +To make things more fun, we start and stop units in two different ways: via +systemctl and via a direct busctl invocation. This gives us a bit more coverage +of different code paths. + +(cherry picked from commit 6854434cfb5dda10c07d95835c38b75e5e71c2b5) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 62 +++++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index d46946fd77..5f061d3629 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -132,19 +132,40 @@ test_hierarchical_service_dropins () { + echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c +- check_ko a-b-c ExecCondition "/bin/echo service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ check_ko a-b-c ExecCondition "echo service.d" ++ check_ko a-b-c ExecCondition "echo a-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-c.service.d" + + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + mkdir -p /usr/lib/systemd/system/$dropin + echo " + [Service] +-ExecCondition=/bin/echo $dropin ++ExecCondition=echo $dropin + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload +- check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ check_ok a-b-c ExecCondition "echo $dropin" ++ ++ # Check that we can start a transient service in presence of the drop-ins ++ systemd-run --unit a-b-c2.service -p Description='sleepy' sleep infinity ++ ++ # The transient setting replaces the default ++ check_ok a-b-c2.service Description "sleepy" ++ ++ # The override takes precedence for ExecCondition ++ # (except the last iteration when it only applies to the other service) ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c2.service Description "sleepy" ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ systemctl stop a-b-c2.service + done + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + rm -rf /usr/lib/systemd/system/$dropin +@@ -169,6 +190,35 @@ MemoryMax=1000000000 + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload + check_ok a-b-c.slice MemoryMax "1000000000" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StartTransientUnit 'ssa(sv)a(sa(sv))' \ ++ 'a-b-c.slice' 'replace' \ ++ 2 \ ++ 'Description' s 'slice too' \ ++ 'MemoryMax' t 1000000002 \ ++ 0 ++ ++ # The override takes precedence for MemoryMax ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ # The transient setting replaces the default ++ check_ok a-b-c.slice Description "slice too" ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ check_ok a-b-c.slice Description "slice too" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StopUnit 'ss' \ ++ 'a-b-c.slice' 'replace' ++ + rm /usr/lib/systemd/system/$dropin/override.conf + done + diff --git a/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch b/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch new file mode 100644 index 0000000..d27d06d --- /dev/null +++ b/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch @@ -0,0 +1,66 @@ +From 832ceb778409cac37c3b64294dc64312e86eedc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 21:52:43 +0200 +Subject: [PATCH] TEST-15: add one more test for drop-in precedence + +(cherry picked from commit c3fa408dcc03bb6dbd11f180540fb9e684893c39) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 36 ++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5f061d3629..f6b3844630 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -233,6 +233,41 @@ MemoryMax=1000000001 + clear_units a-b-c.slice + } + ++test_transient_service_dropins () { ++ echo "Testing dropins for a transient service..." ++ echo "*** test transient service drop-ins" ++ ++ mkdir -p /etc/systemd/system/service.d ++ mkdir -p /etc/systemd/system/a-.service.d ++ mkdir -p /etc/systemd/system/a-b-.service.d ++ mkdir -p /etc/systemd/system/a-b-c.service.d ++ ++ echo -e '[Service]\nStandardInputText=aaa' >/etc/systemd/system/service.d/drop1.conf ++ echo -e '[Service]\nStandardInputText=bbb' >/etc/systemd/system/a-.service.d/drop2.conf ++ echo -e '[Service]\nStandardInputText=ccc' >/etc/systemd/system/a-b-.service.d/drop3.conf ++ echo -e '[Service]\nStandardInputText=ddd' >/etc/systemd/system/a-b-c.service.d/drop4.conf ++ ++ # There's no fragment yet, so this fails ++ systemctl cat a-b-c.service && exit 1 ++ ++ # xxx → eHh4Cg== ++ systemd-run --unit a-b-c.service -p StandardInputData=eHh4Cg== sleep infinity ++ ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ # xxx\naaa\n\bbb\nccc\nddd\n → eHh4… ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ # Do a reload and check again ++ systemctl daemon-reload ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ clear_units a-b-c.service ++ rm /etc/systemd/system/service.d/drop1.conf \ ++ /etc/systemd/system/a-.service.d/drop2.conf \ ++ /etc/systemd/system/a-b-.service.d/drop3.conf ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -420,6 +455,7 @@ test_invalid_dropins () { + test_basic_dropins + test_hierarchical_service_dropins + test_hierarchical_slice_dropins ++test_transient_service_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch b/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch new file mode 100644 index 0000000..a5e1176 --- /dev/null +++ b/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch @@ -0,0 +1,50 @@ +From 79e852a6c50ab2eae16761f128c52ef286c2956b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 14 Aug 2023 15:58:02 +0200 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.9 + +rhel-only + +Resolves: #2231846 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index 3cc7719e99..ddd41646ae 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -334,6 +334,12 @@ + Same as naming scheme rhel-8.7. + + ++ ++ rhel-8.9 ++ ++ Same as naming scheme rhel-8.7. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ef2bb1b08e..0f42c1c007 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -142,6 +142,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, + NAMING_RHEL_8_8 = NAMING_RHEL_8_7, ++ NAMING_RHEL_8_9 = NAMING_RHEL_8_7, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -163,6 +164,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.6", NAMING_RHEL_8_6 }, + { "rhel-8.7", NAMING_RHEL_8_7 }, + { "rhel-8.8", NAMING_RHEL_8_8 }, ++ { "rhel-8.9", NAMING_RHEL_8_9 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/0974-meson-remove-libdw-dependency-from-pstore.patch b/0974-meson-remove-libdw-dependency-from-pstore.patch new file mode 100644 index 0000000..87c5315 --- /dev/null +++ b/0974-meson-remove-libdw-dependency-from-pstore.patch @@ -0,0 +1,27 @@ +From e89c5274a75907bf24689859cdcdf8335df382cd Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 24 Nov 2021 20:23:02 +0000 +Subject: [PATCH] meson: remove libdw dependency from pstore + +systemd-pstore does not use any symbol from libdw, and never did, +but the dependency was listed since the beginning + +(cherry picked from commit 5361f62d6d5b25c6545059f7d2513324be8d7a49) + +Related: #2211416 +--- + meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/meson.build b/meson.build +index d986dd24ac..d00d250444 100644 +--- a/meson.build ++++ b/meson.build +@@ -2161,7 +2161,6 @@ if conf.get('ENABLE_PSTORE') == 1 + link_with : [libshared], + dependencies : [threads, + libacl, +- libdw, + libxz, + liblz4], + install_rpath : rootlibexecdir, diff --git a/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch b/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch new file mode 100644 index 0000000..473087c --- /dev/null +++ b/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch @@ -0,0 +1,113 @@ +From e7f656192ea399043947640a664bd94129e9549b Mon Sep 17 00:00:00 2001 +From: Eric DeVolder +Date: Mon, 13 Apr 2020 16:22:04 -0500 +Subject: [PATCH] pstore: introduce tmpfiles.d/systemd-pstore.conf + +The systemd pstore service archives the contents of /sys/fs/pstore +upon boot so that there is room for a subsequent dump. The issue is +that while the service is present, the kernel still needs to be +configured to write data into the pstore. The kernel has two +parameters, crash_kexec_post_notifiers and printk.always_kmsg_dump, +that control writes into pstore. + +The crash_kexec_post_notifiers parameter enables the kernel to write +dmesg (including stack trace) into pstore upon a panic, and +printk.always_kmsg_dump parameter enables the kernel to write dmesg +upon a shutdown (shutdown, reboot, halt). + +As it stands today, these parameters are not managed/manipulated by +the systemd pstore service, and are solely reliant upon the user [to +have the foresight] to set them on the kernel command line at boot, or +post boot via sysfs. Furthermore, the user would need to set these +parameters in a persistent fashion so that that they are enabled on +subsequent reboots. + +This patch introduces the setting of these two kernel parameters via +the systemd tmpfiles technique. + +(cherry picked from commit f00c36641a253f4ea659ec3def5d87ba1336eb3b) + +Resolves: #2211416 +--- + man/systemd-pstore.service.xml | 18 ++++++++++++++++++ + tmpfiles.d/meson.build | 1 + + tmpfiles.d/systemd-pstore.conf | 29 +++++++++++++++++++++++++++++ + 3 files changed, 48 insertions(+) + create mode 100644 tmpfiles.d/systemd-pstore.conf + +diff --git a/man/systemd-pstore.service.xml b/man/systemd-pstore.service.xml +index 47916da521..335a3b3d18 100644 +--- a/man/systemd-pstore.service.xml ++++ b/man/systemd-pstore.service.xml +@@ -81,6 +81,24 @@ + pstore.conf5. + + ++ ++ ++ Controlling kernel parameters ++ ++ The kernel has two parameters, ++ /sys/module/kernel/parameters/crash_kexec_post_notifiers and ++ /sys/module/printk/parameters/always_kmsg_dump, ++ that control writes into pstore. ++ The crash_kexec_post_notifiers parameter enables the kernel to write ++ dmesg (including stack trace) into pstore upon a panic or crash, and ++ printk.always_kmsg_dump parameter enables the kernel to write dmesg ++ upon a normal shutdown (shutdown, reboot, halt). These kernel ++ parameters are managed via the ++ tmpfiles.d5 ++ mechanism, specifically the file /usr/lib/tmpfiles/systemd-pstore.conf. ++ ++ ++ + + + +diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build +index 35eea2be5c..5ebb8f432a 100644 +--- a/tmpfiles.d/meson.build ++++ b/tmpfiles.d/meson.build +@@ -7,6 +7,7 @@ tmpfiles = [['home.conf', ''], + ['systemd-nologin.conf', ''], + ['systemd-nspawn.conf', 'ENABLE_MACHINED'], + ['portables.conf', 'ENABLE_PORTABLED'], ++ ['systemd-pstore.conf', 'ENABLE_PSTORE'], + ['tmp.conf', ''], + ['x11.conf', ''], + ['legacy.conf', 'HAVE_SYSV_COMPAT'], +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +new file mode 100644 +index 0000000000..cb600ec1ee +--- /dev/null ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -0,0 +1,29 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# The systemd-pstore.service(1) archives the contents of /sys/fs/pstore ++# upon boot so that there is room for a subsequent dump. This service ++# is enabled with: ++# systemctl enable systemd-pstore ++# ++# With the service enabled, the kernel still needs to be configured ++# to write data into the pstore. The kernel has two parameters, ++# crash_kexec_post_notifiers and printk.always_kmsg_dump, that ++# control writes into pstore. ++# ++# The crash_kexec_post_notifiers parameter enables the kernel to write ++# dmesg (including stack trace) into pstore upon a panic, and ++# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# upon a normal shutdown (shutdown, reboot, halt). ++# ++# To configure the kernel parameters, uncomment the appropriate ++# line(s) below. The value written is either 'Y' to enable the ++# kernel parameter, or 'N' to disable the kernel parameter. ++# ++# After making a change to this file, do: ++# systemd-tmpfiles --create path/to/tmpfiles.d/systemd-pstore.conf ++# ++# These changes are automatically applied on future re-boots. ++ ++d /var/lib/systemd/pstore 0755 root root 14d ++#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch b/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch new file mode 100644 index 0000000..4dec077 --- /dev/null +++ b/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch @@ -0,0 +1,25 @@ +From fec31cf3f20aa97b7dc8b381e64f30eea4d4c2d2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 May 2020 16:11:51 +0200 +Subject: [PATCH] tmpfiles: don't complain if we can't enable pstore in + containers + +(cherry picked from commit 203c07c95b91b4ae3b0c1ae3c92accdb71fd5e13) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index cb600ec1ee..8b6a1dafc3 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -25,5 +25,5 @@ + # These changes are automatically applied on future re-boots. + + d /var/lib/systemd/pstore 0755 root root 14d +-#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch b/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch new file mode 100644 index 0000000..1824a74 --- /dev/null +++ b/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch @@ -0,0 +1,66 @@ +From 21e0afbe2764476c98d7809af6634773835723d4 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Tue, 4 Aug 2020 17:30:51 +0800 +Subject: [PATCH] pstore: don't enable crash_kexec_post_notifiers by default + +commit f00c36641a253f4ea659ec3def5d87ba1336eb3b enabled +crash_kexec_post_notifiers by default regardless of whether pstore +is enabled or not. + +The original intention to enabled this option by default is that +it only affects kernel post-panic behavior, so should have no harm. +But this is not true if the user wants a reliable kdump. + +crash_kexec_post_notifiers is known to cause problem with kdump, +and it's documented in kernel. It's not easy to fix the problem +because of how kdump works. Kdump expects the crashed kernel to +jump to an pre-loaded crash kernel, so doing any extra job before +the jump will increase the risk. + +It depends on the user to choose between having a reliable kdump or +some other post-panic debug mechanic. + +So it's better to keep this config untouched by default, or it may put +kdump at higher risk of failing silently. User should enable it by +uncommenting the config line manually if pstore is always needed. + +Also add a inline comment inform user about the potential issue. + +Thanks to Dave Young for finding out this issue. + +Fixes #16661 + +Signed-off-by: Kairui Song +(cherry picked from commit edb8c98446e7dae54bcda90806bf6c068e1c6385) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index 8b6a1dafc3..e8e9ed48ae 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -11,8 +11,13 @@ + # control writes into pstore. + # + # The crash_kexec_post_notifiers parameter enables the kernel to write +-# dmesg (including stack trace) into pstore upon a panic, and +-# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# dmesg (including stack trace) into pstore upon a panic even if kdump ++# is loaded, only needed if you want to use pstore with kdump. Without ++# this parameter, kdump could block writing to pstore for stability ++# reason. Note this increases the risk of kdump failure even if pstore ++# is not available. ++# ++# The printk.always_kmsg_dump parameter enables the kernel to write dmesg + # upon a normal shutdown (shutdown, reboot, halt). + # + # To configure the kernel parameters, uncomment the appropriate +@@ -26,4 +31,4 @@ + + d /var/lib/systemd/pstore 0755 root root 14d + #w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch b/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch new file mode 100644 index 0000000..cf88994 --- /dev/null +++ b/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch @@ -0,0 +1,217 @@ +From 44d19e4beb486969b25c07f7efdee2e8b8bcf986 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:19:07 +0100 +Subject: [PATCH] core: when Delegate=yes is set for a unit, run ExecStartPre= + and friends in a subcgroup of the unit + +Otherwise we might conflict with the "no-processes-in-inner-cgroup" rule +of cgroupsv2. Consider nspawn starting up and initializing its cgroup +hierarchy with "supervisor/" and "payload/" as subcgroup, with itself +moved into the former and the payload into the latter. Now, if an +ExecStartPre= is run right after it cannot be placed in the main cgroup, +because that is now in inner cgroup with populated children. + +Hence, let's run these helpers in another sub-cgroup .control/ below it. + +This is somewhat ugly since it weakens the clear separation of +ownership, but given that this is an explicit contract, and double opt-in should be acceptable. + +Fixes: #10482 +(cherry picked from commit 78f93209fc7f61f15b12d7a5f74d712bd020b249) + +Resolves: #2215925 +--- + src/core/execute.c | 67 +++++++++++++++++++++++++++++++++++++++------- + src/core/execute.h | 9 ++++--- + src/core/service.c | 13 ++++----- + 3 files changed, 70 insertions(+), 19 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index b1d8dceb32..7e186c948c 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2834,6 +2834,37 @@ bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) { + return c->cpu_affinity_from_numa; + } + ++static int exec_parameters_get_cgroup_path(const ExecParameters *params, char **ret) { ++ bool using_subcgroup; ++ char *p; ++ ++ assert(params); ++ assert(ret); ++ ++ if (!params->cgroup_path) ++ return -EINVAL; ++ ++ /* If we are called for a unit where cgroup delegation is on, and the payload created its own populated ++ * subcgroup (which we expect it to do, after all it asked for delegation), then we cannot place the control ++ * processes started after the main unit's process in the unit's main cgroup because it is now an inner one, ++ * and inner cgroups may not contain processes. Hence, if delegation is on, and this is a control process, ++ * let's use ".control" as subcgroup instead. Note that we do so only for ExecStartPost=, ExecReload=, ++ * ExecStop=, ExecStopPost=, i.e. for the commands where the main process is already forked. For ExecStartPre= ++ * this is not necessary, the cgroup is still empty. We distinguish these cases with the EXEC_CONTROL_CGROUP ++ * flag, which is only passed for the former statements, not for the latter. */ ++ ++ using_subcgroup = FLAGS_SET(params->flags, EXEC_CONTROL_CGROUP|EXEC_CGROUP_DELEGATE|EXEC_IS_CONTROL); ++ if (using_subcgroup) ++ p = strjoin(params->cgroup_path, "/.control"); ++ else ++ p = strdup(params->cgroup_path); ++ if (!p) ++ return -ENOMEM; ++ ++ *ret = p; ++ return using_subcgroup; ++} ++ + static int exec_child( + Unit *unit, + const ExecCommand *command, +@@ -3055,10 +3086,18 @@ static int exec_child( + } + + if (params->cgroup_path) { +- r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL); ++ _cleanup_free_ char *p = NULL; ++ ++ r = exec_parameters_get_cgroup_path(params, &p); + if (r < 0) { + *exit_status = EXIT_CGROUP; +- return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", params->cgroup_path); ++ return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m"); ++ } ++ ++ r = cg_attach_everywhere(params->cgroup_supported, p, 0, NULL, NULL); ++ if (r < 0) { ++ *exit_status = EXIT_CGROUP; ++ return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", p); + } + } + +@@ -3659,6 +3698,7 @@ int exec_spawn(Unit *unit, + DynamicCreds *dcreds, + pid_t *ret) { + ++ _cleanup_free_ char *subcgroup_path = NULL; + _cleanup_strv_free_ char **files_env = NULL; + int *fds = NULL; + size_t n_storage_fds = 0, n_socket_fds = 0; +@@ -3716,6 +3756,17 @@ int exec_spawn(Unit *unit, + LOG_UNIT_ID(unit), + LOG_UNIT_INVOCATION_ID(unit)); + ++ if (params->cgroup_path) { ++ r = exec_parameters_get_cgroup_path(params, &subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to acquire subcgroup path: %m"); ++ if (r > 0) { /* We are using a child cgroup */ ++ r = cg_create(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to create control group '%s': %m", subcgroup_path); ++ } ++ } ++ + pid = fork(); + if (pid < 0) + return log_unit_error_errno(unit, errno, "Failed to fork: %m"); +@@ -3754,13 +3805,11 @@ int exec_spawn(Unit *unit, + + log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid); + +- /* We add the new process to the cgroup both in the child (so +- * that we can be sure that no user code is ever executed +- * outside of the cgroup) and in the parent (so that we can be +- * sure that when we kill the cgroup the process will be +- * killed too). */ +- if (params->cgroup_path) +- (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid); ++ /* We add the new process to the cgroup both in the child (so that we can be sure that no user code is ever ++ * executed outside of the cgroup) and in the parent (so that we can be sure that when we kill the cgroup the ++ * process will be killed too). */ ++ if (subcgroup_path) ++ (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path, pid); + + exec_status_start(&command->exec_status, pid); + +diff --git a/src/core/execute.h b/src/core/execute.h +index 62c6229621..f5bc180ece 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -289,12 +289,13 @@ typedef enum ExecFlags { + EXEC_CHOWN_DIRECTORIES = 1 << 5, /* chown() the runtime/state/cache/log directories to the user we run as, under all conditions */ + EXEC_NSS_BYPASS_BUS = 1 << 6, /* Set the SYSTEMD_NSS_BYPASS_BUS environment variable, to disable nss-systemd for dbus */ + EXEC_CGROUP_DELEGATE = 1 << 7, ++ EXEC_IS_CONTROL = 1 << 8, ++ EXEC_CONTROL_CGROUP = 1 << 9, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */ + + /* The following are not used by execute.c, but by consumers internally */ +- EXEC_PASS_FDS = 1 << 8, +- EXEC_IS_CONTROL = 1 << 9, +- EXEC_SETENV_RESULT = 1 << 10, +- EXEC_SET_WATCHDOG = 1 << 11, ++ EXEC_PASS_FDS = 1 << 10, ++ EXEC_SETENV_RESULT = 1 << 11, ++ EXEC_SET_WATCHDOG = 1 << 12, + } ExecFlags; + + struct ExecParameters { +diff --git a/src/core/service.c b/src/core/service.c +index e05d0e0514..0423f2c73e 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1429,7 +1429,7 @@ static int service_spawn( + assert(c); + assert(_pid); + +- r = unit_prepare_exec(UNIT(s)); ++ r = unit_prepare_exec(UNIT(s)); /* This realizes the cgroup, among other things */ + if (r < 0) + return r; + +@@ -1798,7 +1798,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1913,7 +1913,7 @@ static void service_enter_stop(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1991,7 +1991,7 @@ static void service_enter_start_post(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2269,7 +2269,7 @@ static void service_enter_reload(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2309,7 +2309,8 @@ static void service_run_next_control(Service *s) { + timeout, + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL| + (IN_SET(s->control_command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)| +- (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0), ++ (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0)| ++ (IN_SET(s->control_command_id, SERVICE_EXEC_START_POST, SERVICE_EXEC_RELOAD, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_CONTROL_CGROUP : 0), + &s->control_pid); + if (r < 0) + goto fail; diff --git a/0979-man-link-Delegate-documentation-up-with-the-markdown.patch b/0979-man-link-Delegate-documentation-up-with-the-markdown.patch new file mode 100644 index 0000000..a28e88d --- /dev/null +++ b/0979-man-link-Delegate-documentation-up-with-the-markdown.patch @@ -0,0 +1,26 @@ +From 0c1f96220f2a42c256a1e22e5f16d2ff8f4144df Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:29:02 +0100 +Subject: [PATCH] man: link Delegate= documentation up with the markdown docs + +(cherry picked from commit 077c40bc5271dfc8d9cee179fbed27a27e741973) + +Related: #2215925 +--- + man/systemd.resource-control.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index d3bff29169..36a622ebf0 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -808,6 +808,9 @@ + specific to the unified hierarchy while others are specific to the legacy hierarchy. Also note that the + kernel might support further controllers, which aren't covered here yet as delegation is either not supported + at all for them or not defined cleanly. ++ ++ For further details on the delegation model consult Control Group APIs and Delegation. + + + diff --git a/10000-core-fix-a-null-reference-case-in-load_from_path.patch b/10000-core-fix-a-null-reference-case-in-load_from_path.patch deleted file mode 100644 index e15690c..0000000 --- a/10000-core-fix-a-null-reference-case-in-load_from_path.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 11e4aae398f9d26c7c4e54bfa6621f80a3ed2100 Mon Sep 17 00:00:00 2001 -From: Wen Yang -Date: Tue, 19 Apr 2022 11:04:47 +0800 -Subject: [PATCH] fix a null reference case in load_from_path() - ---- - src/core/load-fragment.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c -index c0b1fd4..f59a040 100644 ---- a/src/core/load-fragment.c -+++ b/src/core/load-fragment.c -@@ -4477,7 +4477,6 @@ static int load_from_path(Unit *u, const char *path) { - r = open_follow(&filename, &f, symlink_names, &id); - if (r >= 0) - break; -- filename = mfree(filename); - - /* ENOENT means that the file is missing or is a dangling symlink. - * ENOTDIR means that one of paths we expect to be is a directory -@@ -4486,7 +4485,8 @@ static int load_from_path(Unit *u, const char *path) { - */ - if (r == -EACCES) - log_debug_errno(r, "Cannot access \"%s\": %m", filename); -- else if (!IN_SET(r, -ENOENT, -ENOTDIR)) -+ filename = mfree(filename); -+ if (!IN_SET(r, -ENOENT, -ENOTDIR)) - return r; - - /* Empty the symlink names for the next run */ --- -2.27.0 - diff --git a/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch b/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch deleted file mode 100644 index ec09ee4..0000000 --- a/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 1b3f7805ed7c193e17cb5bad4f4f19c2f72f3d08 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Tue, 19 Apr 2022 11:16:42 +0800 -Subject: [PATCH] sysctl: Don't pass null directive argument to '%s' - ---- - src/sysctl/sysctl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c -index 4c85d68..e756eff 100644 ---- a/src/sysctl/sysctl.c -+++ b/src/sysctl/sysctl.c -@@ -160,7 +160,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign - - value = strchr(p, '='); - if (!value) { -- log_error("Line is not an assignment at '%s:%u': %s", path, c, value); -+ log_error("Line is not an assignment at '%s:%u': %s", path, c, p); - - if (r == 0) - r = -EINVAL; --- -2.27.0 - diff --git a/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch b/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch deleted file mode 100644 index 66539a0..0000000 --- a/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch +++ /dev/null @@ -1,52 +0,0 @@ -From f7940c9cdf872d7504aca9637e9fd14328b2b726 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 19 Apr 2022 11:26:10 +0800 -Subject: [PATCH] exit-status: introduce EXIT_EXCEPTION mapping to 255 - ---- - src/basic/exit-status.c | 9 ++++++--- - src/basic/exit-status.h | 1 + - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c -index 0a7a53b..8b67d44 100644 ---- a/src/basic/exit-status.c -+++ b/src/basic/exit-status.c -@@ -19,9 +19,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { - * 79…199 │ (Currently unmapped) - * 200…241 │ systemd's private error codes (might be extended to 254 in future development) - * 242…254 │ (Currently unmapped, but see above) -- * 255 │ (We should probably stay away from that one, it's frequently used by applications to indicate an -- * │ exit reason that cannot really be expressed in a single exit status value — such as a propagated -- * │ signal or such) -+ * 255 │ EXIT_EXCEPTION (We use this to propagate exit-by-signal events. It's frequently used by others apps (like bash) -+ * │ to indicate exit reason that cannot really be expressed in a single exit status value — such as a propagated -+ * │ signal or such, and we follow that logic here.) - */ - - switch (status) { /* We always cover the ISO C ones */ -@@ -158,6 +158,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { - - case EXIT_NUMA_POLICY: - return "NUMA_POLICY"; -+ -+ case EXIT_EXCEPTION: -+ return "EXCEPTION"; - } - } - -diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h -index dc284aa..e923247 100644 ---- a/src/basic/exit-status.h -+++ b/src/basic/exit-status.h -@@ -70,6 +70,7 @@ enum { - EXIT_LOGS_DIRECTORY, /* 240 */ - EXIT_CONFIGURATION_DIRECTORY, - EXIT_NUMA_POLICY, -+ EXIT_EXCEPTION = 255, /* Whenever we want to propagate an abnormal/signal exit, in line with bash */ - }; - - typedef enum ExitStatusLevel { --- -2.27.0 - diff --git a/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch b/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch deleted file mode 100644 index 026fc66..0000000 --- a/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From dffb92b5520a4b539f0466d4161fcaacc6ba5ba8 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 19 Apr 2022 11:34:27 +0800 -Subject: [PATCH] main: don't freeze PID 1 in containers, exit with - ---- - src/core/main.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/src/core/main.c b/src/core/main.c -index d897155..0aec5d1 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -139,7 +139,13 @@ static NUMAPolicy arg_numa_policy; - static int parse_configuration(const struct rlimit *saved_rlimit_nofile, - const struct rlimit *saved_rlimit_memlock); - --_noreturn_ static void freeze_or_reboot(void) { -+_noreturn_ static void freeze_or_exit_or_reboot(void) { -+ /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the -+ * container manager, and thus inform it that something went wrong. */ -+ if (detect_container() > 0) { -+ log_emergency("Exiting PID 1..."); -+ exit(EXIT_EXCEPTION); -+ } - - if (arg_crash_reboot) { - log_notice("Rebooting in 10s..."); -@@ -247,7 +253,7 @@ _noreturn_ static void crash(int sig) { - } - } - -- freeze_or_reboot(); -+ freeze_or_exit_or_reboot(); - } - - static void install_crash_handler(void) { -@@ -2664,9 +2670,9 @@ finish: - if (error_message) - manager_status_printf(NULL, STATUS_TYPE_EMERGENCY, - ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL, -- "%s, freezing.", error_message); -- freeze_or_reboot(); -+ "%s.", error_message); -+ freeze_or_exit_or_reboot(); - } - - reset_arguments(); - return retval; --- -2.27.0 - diff --git a/10004-Do-not-go-into-freeze-when-systemd-crashd.patch b/10004-Do-not-go-into-freeze-when-systemd-crashd.patch deleted file mode 100644 index 1cb12cc..0000000 --- a/10004-Do-not-go-into-freeze-when-systemd-crashd.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 64072aab92ff6489a2e460a9bdd1cfefa587264b Mon Sep 17 00:00:00 2001 -From: Yuanhong Peng -Date: Tue, 19 Apr 2022 13:36:09 +0800 -Subject: [PATCH] Do not go into freeze when systemd crashd - ---- - src/core/main.c | 41 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 40 insertions(+), 1 deletion(-) - -diff --git a/src/core/main.c b/src/core/main.c -index 0aec5d1..db91151 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -10,6 +11,7 @@ - #include - #include - #include -+#include - #include - #if HAVE_SECCOMP - #include -@@ -135,10 +137,41 @@ static sd_id128_t arg_machine_id; - static EmergencyAction arg_cad_burst_action; - static CPUSet arg_cpu_affinity; - static NUMAPolicy arg_numa_policy; -+static bool reexec_jmp_can = false; -+static bool reexec_jmp_inited = false; -+static sigjmp_buf reexec_jmp_buf; - - static int parse_configuration(const struct rlimit *saved_rlimit_nofile, - const struct rlimit *saved_rlimit_memlock); - -+static void reexec_handler(int sig) { -+ reexec_jmp_can = true; -+} -+ -+_noreturn_ static void freeze_wait_upgrade(void) { -+ struct sigaction sa; -+ sigset_t ss; -+ -+ sigemptyset(&ss); -+ sigaddset(&ss, SIGTERM); -+ sigprocmask(SIG_UNBLOCK, &ss, NULL); -+ -+ sa.sa_handler = reexec_handler; -+ sa.sa_flags = SA_RESTART; -+ sigaction(SIGTERM, &sa, NULL); -+ -+ log_error("freeze_wait_upgrade: %d\n", reexec_jmp_inited); -+ reexec_jmp_can = false; -+ while(1) { -+ usleep(10000); -+ if (reexec_jmp_inited && reexec_jmp_can) { -+ log_error("goto manager_reexecute.\n"); -+ siglongjmp(reexec_jmp_buf, 1); -+ } -+ waitpid(-1, NULL, WNOHANG); -+ } -+} -+ - _noreturn_ static void freeze_or_exit_or_reboot(void) { - /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the - * container manager, and thus inform it that something went wrong. */ -@@ -157,7 +190,8 @@ _noreturn_ static void freeze_or_exit_or_reboot(void) { - } - - log_emergency("Freezing execution."); -- freeze(); -+ freeze_wait_upgrade(); -+ - } - - _noreturn_ static void crash(int sig) { -@@ -1667,6 +1701,10 @@ static int invoke_main_loop( - assert(ret_switch_root_init); - assert(ret_error_message); - -+ reexec_jmp_inited = true; -+ if (sigsetjmp(reexec_jmp_buf, 1)) -+ goto manager_reexecute; -+ - for (;;) { - r = manager_loop(m); - if (r < 0) { -@@ -1709,6 +1747,7 @@ static int invoke_main_loop( - - case MANAGER_REEXECUTE: - -+manager_reexecute: - r = prepare_reexecute(m, &arg_serialization, ret_fds, false); - if (r < 0) { - *ret_error_message = "Failed to prepare for reexecution"; --- -2.27.0 - diff --git a/10005-mount-setup-change-the-system-mount-propagation-to-s.patch b/10005-mount-setup-change-the-system-mount-propagation-to-s.patch deleted file mode 100644 index fa95141..0000000 --- a/10005-mount-setup-change-the-system-mount-propagation-to-s.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0c7f29561634f9374c0d9042304f4d4caa4242f0 Mon Sep 17 00:00:00 2001 -From: Wen Yang -Date: Tue, 19 Apr 2022 13:50:04 +0800 -Subject: [PATCH] mount-setup: change the system mount propagation to - ---- - src/core/main.c | 2 +- - src/core/mount-setup.c | 4 ++-- - src/core/mount-setup.h | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/core/main.c b/src/core/main.c -index db91151..81dae1c 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -2519,7 +2519,7 @@ int main(int argc, char *argv[]) { - if (!skip_setup) - kmod_setup(); - -- r = mount_setup(loaded_policy); -+ r = mount_setup(loaded_policy, skip_setup); - if (r < 0) { - error_message = "Failed to mount API filesystems"; - goto finish; -diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c -index a659458..9f9f953 100644 ---- a/src/core/mount-setup.c -+++ b/src/core/mount-setup.c -@@ -400,7 +400,7 @@ static int relabel_cgroup_filesystems(void) { - } - #endif - --int mount_setup(bool loaded_policy) { -+int mount_setup(bool loaded_policy, bool leave_propagation) { - int r = 0; - - r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy); -@@ -444,7 +444,7 @@ int mount_setup(bool loaded_policy) { - * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a - * container manager we assume the container manager knows what it is doing (for example, because it set up - * some directories with different propagation modes). */ -- if (detect_container() <= 0) -+ if (detect_container() <= 0 && !leave_propagation) - if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) - log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m"); - -diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h -index 43cd890..7a011b2 100644 ---- a/src/core/mount-setup.h -+++ b/src/core/mount-setup.h -@@ -4,7 +4,7 @@ - #include - - int mount_setup_early(void); --int mount_setup(bool loaded_policy); -+int mount_setup(bool loaded_policy, bool leave_propagation); - - int mount_cgroup_controllers(char ***join_controllers); - --- -2.27.0 - diff --git a/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch b/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch deleted file mode 100644 index 9a5fa6e..0000000 --- a/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d449667a6a545a46647911838731e8e46a5a39ed Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 19 Apr 2022 13:56:39 +0800 -Subject: [PATCH] cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() - unsigned - ---- - src/basic/cgroup-util.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h -index 1210b38..76659c3 100644 ---- a/src/basic/cgroup-util.h -+++ b/src/basic/cgroup-util.h -@@ -31,7 +31,7 @@ typedef enum CGroupController { - _CGROUP_CONTROLLER_INVALID = -1, - } CGroupController; - --#define CGROUP_CONTROLLER_TO_MASK(c) (1 << (c)) -+#define CGROUP_CONTROLLER_TO_MASK(c) (1U << (c)) - - /* A bit mask of well known cgroup controllers */ - typedef enum CGroupMask { --- -2.27.0 - diff --git a/10007-cgroup-update-only-siblings-that-got-realized-once.patch b/10007-cgroup-update-only-siblings-that-got-realized-once.patch deleted file mode 100644 index 068f21c..0000000 --- a/10007-cgroup-update-only-siblings-that-got-realized-once.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 841539281bed5187d2f773097eefb0bb3c5057ec Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 19 Apr 2022 14:03:12 +0800 -Subject: [PATCH] cgroup: update only siblings that got realized once - ---- - src/core/cgroup.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index f02cc31..e0e0a98 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -1980,7 +1980,16 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { - Unit *slice; - - /* This adds the siblings of the specified unit and the siblings of all parent units to the cgroup -- * queue. (But neither the specified unit itself nor the parents.) */ -+ * queue. (But neither the specified unit itself nor the parents.) -+ * -+ * Propagation of realization "side-ways" (i.e. towards siblings) is in relevant on cgroup-v1 where -+ * scheduling become very weird if two units that own processes reside in the same slice, but one is -+ * realized in the "cpu" hierarchy and once is not (for example because one has CPUWeight= set and -+ * the other does not), because that means processes need to be scheduled against groups. Let's avoid -+ * this asymmetry by always ensuring that units below a slice that are realized at all are hence -+ * always realized in *all* their hierarchies, and it is sufficient for a unit's sibling to be -+ * realized for a unit to be realized too. */ -+ - - while ((slice = UNIT_DEREF(u->slice))) { - Iterator i; -@@ -1996,6 +2005,11 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { - if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(m))) - continue; - -+ /* We only enqueue siblings if they were realized once at least, in the main -+ * hierarchy. */ -+ if (!m->cgroup_realized) -+ continue; -+ - /* If the unit doesn't need any new controllers and has current ones realized, it - * doesn't need any changes. */ - if (unit_has_mask_realized(m, --- -2.27.0 - diff --git a/10008-core-add-a-config-item-to-support-setting-the-value-.patch b/10008-core-add-a-config-item-to-support-setting-the-value-.patch deleted file mode 100644 index 272d61b..0000000 --- a/10008-core-add-a-config-item-to-support-setting-the-value-.patch +++ /dev/null @@ -1,120 +0,0 @@ -From f21d63650318791f29f56dc26f23acb5b53620a6 Mon Sep 17 00:00:00 2001 -From:Yuanhong Peng -Date: Tue, 19 Apr 2022 14:13:49 +0800 -Subject: [PATCH] core: add a config item to support setting the value - ---- - src/core/main.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 69 insertions(+) - -diff --git a/src/core/main.c b/src/core/main.c -index 81dae1c..0712423 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -140,6 +140,7 @@ static NUMAPolicy arg_numa_policy; - static bool reexec_jmp_can = false; - static bool reexec_jmp_inited = false; - static sigjmp_buf reexec_jmp_buf; -+static bool arg_default_cpuset_clone_children = false; - - static int parse_configuration(const struct rlimit *saved_rlimit_nofile, - const struct rlimit *saved_rlimit_memlock); -@@ -527,6 +528,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat - return 0; - - parse_path_argument_and_warn(value, false, &arg_watchdog_device); -+ -+ } else if (proc_cmdline_key_streq(key, "systemd.cpuset_clone_children") && value) { -+ -+ r = parse_boolean(value); -+ if (r < 0) -+ log_warning("Failed to parse cpuset_clone_children switch %s. Ignoring.", value); -+ else -+ arg_default_cpuset_clone_children = r; - - } else if (streq(key, "quiet") && !value) { - -@@ -756,6 +765,7 @@ static int parse_config_file(void) { - { "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting }, - { "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max }, - { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action }, -+ { "Manager", "DefaultCPUSetCloneChildren",config_parse_bool, 0, &arg_default_cpuset_clone_children }, - {} - }; - -@@ -1872,6 +1882,64 @@ static void log_execution_mode(bool *ret_first_boot) { - } - } - -+static bool is_use_triple_cgroup(void) { -+ const char * path ="/sys/fs/cgroup/cpuset"; -+ _cleanup_strv_free_ char **l = NULL; -+ char buf[128] = {0}; -+ int r; -+ -+ r = is_symlink(path); -+ if (r <= 0) -+ return false; -+ -+ r = readlink(path, buf, sizeof(buf)); -+ if (r < 0 || (unsigned int)r >= sizeof(buf)) -+ return false; -+ -+ buf[r] = '\0'; -+ l = strv_split(buf, ","); -+ if (!l) -+ return false; -+ -+ strv_sort(l); -+ if (strv_length(l) != 3) -+ return false; -+ -+ if (streq(l[0],"cpu") && streq(l[1], "cpuacct") && -+ streq(l[2], "cpuset")) { -+ log_debug(PACKAGE_STRING " use_triple_cgroup: %s", buf); -+ return true; -+ } -+ return false; -+} -+ -+static int ali_handle_cpuset_clone_children(void) -+{ -+ const char *file = "/sys/fs/cgroup/cpuset/cgroup.clone_children"; -+ _cleanup_free_ char *buf = NULL; -+ int r; -+ -+ r = read_one_line_file(file, &buf); -+ if (r < 0) { -+ log_warning_errno(r, "Cannot read %s: %m", file); -+ return r; -+ } -+ -+ if (streq(buf, "1") && arg_default_cpuset_clone_children) -+ return 0; -+ -+ if (streq(buf, "0") && (!arg_default_cpuset_clone_children)) -+ return 0; -+ -+ if (!is_use_triple_cgroup()) -+ return 0; -+ -+ r = write_string_file(file, one_zero(arg_default_cpuset_clone_children), 0); -+ log_info(PACKAGE_STRING " set %s to %s, ret=%d", file, one_zero(arg_default_cpuset_clone_children), r); -+ return r; -+} -+ -+ - static int initialize_runtime( - bool skip_setup, - struct rlimit *saved_rlimit_nofile, -@@ -1906,6 +1974,7 @@ static int initialize_runtime( - return r; - } - -+ ali_handle_cpuset_clone_children(); - status_welcome(); - hostname_setup(); - machine_id_setup(NULL, arg_machine_id, NULL); --- -2.27.0 - diff --git a/10009-systemd-anolis-support-loongarch64.patch b/10009-systemd-anolis-support-loongarch64.patch deleted file mode 100644 index b76c8e0..0000000 --- a/10009-systemd-anolis-support-loongarch64.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c8b7c2b34bd451cd9d5904fc215ad14893008a03 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Tue, 19 Apr 2022 14:25:05 +0800 -Subject: [PATCH] support loongarch64 for systemd - ---- - src/basic/architecture.c | 3 +++ - src/basic/architecture.h | 4 ++++ - 2 files changed, 7 insertions(+) - -diff --git a/src/basic/architecture.c b/src/basic/architecture.c -index 85837b5..96bbf97 100644 ---- a/src/basic/architecture.c -+++ b/src/basic/architecture.c -@@ -118,6 +118,8 @@ int uname_architecture(void) { - #elif defined(__arc__) - { "arc", ARCHITECTURE_ARC }, - { "arceb", ARCHITECTURE_ARC_BE }, -+#elif defined(__loongarch64) -+ { "loongarch64", ARCHITECTURE_LOONGARCH64 }, - #else - #error "Please register your architecture here!" - #endif -@@ -173,6 +175,7 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = { - [ARCHITECTURE_RISCV64] = "riscv64", - [ARCHITECTURE_ARC] = "arc", - [ARCHITECTURE_ARC_BE] = "arc-be", -+ [ARCHITECTURE_LOONGARCH64] = "loongarch64", - }; - - DEFINE_STRING_TABLE_LOOKUP(architecture, int); -diff --git a/src/basic/architecture.h b/src/basic/architecture.h -index 443e890..22e9108 100644 ---- a/src/basic/architecture.h -+++ b/src/basic/architecture.h -@@ -44,6 +44,7 @@ enum { - ARCHITECTURE_RISCV64, - ARCHITECTURE_ARC, - ARCHITECTURE_ARC_BE, -+ ARCHITECTURE_LOONGARCH64, - _ARCHITECTURE_MAX, - _ARCHITECTURE_INVALID = -1 - }; -@@ -229,6 +230,9 @@ int uname_architecture(void); - # define native_architecture() ARCHITECTURE_ARC - # define LIB_ARCH_TUPLE "arc-linux" - # endif -+#elif defined(__loongarch64) -+# define native_architecture() ARCHITECTURE_LOONGARCH64 -+# define LIB_ARCH_TUPLE "loongarch64-linux-gnu" - #else - # error "Please register your architecture here!" - #endif --- -2.27.0 - diff --git a/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch b/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch deleted file mode 100644 index d4054b4..0000000 --- a/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 5209a26aa917aa54b09ee18394ad46ee601e77be Mon Sep 17 00:00:00 2001 -From: Yuanhong Peng -Date: Tue, 17 May 2022 21:34:34 +0800 -Subject: [PATCH] test-catalog: Fix coredump when compiled under GCC10 - -According to the documentation: -https://gcc.gnu.org/gcc-9/porting_to.html#complit: - -The `catalog_dirs` produced by STRV_MAKE(..) marco relies on -the extended lifetime feature which is fixed by GCC9. - -Signed-off-by: Yuanhong Peng ---- - src/journal/test-catalog.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c -index 0c4da29..2ce92af 100644 ---- a/src/journal/test-catalog.c -+++ b/src/journal/test-catalog.c -@@ -201,7 +201,8 @@ static void test_catalog_file_lang(void) { - - int main(int argc, char *argv[]) { - _cleanup_(unlink_tempfilep) char database[] = "/tmp/test-catalog.XXXXXX"; -- _cleanup_free_ char *text = NULL, *catalog_dir = NULL; -+ _cleanup_free_ char *text = NULL; -+ char *catalog_dir = CATALOG_DIR; - int r; - - setlocale(LC_ALL, "de_DE.UTF-8"); -@@ -214,10 +215,9 @@ int main(int argc, char *argv[]) { - * If it is not, e.g. installed by systemd-tests package, then use installed catalogs. */ - if (test_is_running_from_builddir(NULL)) { - assert_se(catalog_dir = path_join(NULL, ABS_BUILD_DIR, "catalog")); -- catalog_dirs = STRV_MAKE(catalog_dir); -- } else -- catalog_dirs = STRV_MAKE(CATALOG_DIR); -+ } - -+ catalog_dirs = STRV_MAKE(catalog_dir); - assert_se(access(catalog_dirs[0], F_OK) >= 0); - log_notice("Using catalog directory '%s'", catalog_dirs[0]); - -@@ -242,5 +242,9 @@ int main(int argc, char *argv[]) { - assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0); - printf(">>>%s<<<\n", text); - -+ /* Only in this case, catalog_dir is malloced */ -+ if (test_is_running_from_builddir(NULL)) -+ free(catalog_dir); -+ - return 0; - } --- -2.27.0 - diff --git a/10011-hwdb-add-Iluvatar-CoreX.patch b/10011-hwdb-add-Iluvatar-CoreX.patch deleted file mode 100644 index e08657c..0000000 --- a/10011-hwdb-add-Iluvatar-CoreX.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 28e47526dce925e6f32cf79825d38fd10e1f442a Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Tue, 26 Jul 2022 22:01:58 +0800 -Subject: [PATCH] hwdb: add Iluvatar CoreX - -Signed-off-by: rpm-build ---- - hwdb/20-pci-vendor-model.hwdb | 6 ++++++ - hwdb/pci.ids | 2 ++ - 2 files changed, 8 insertions(+) - -diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb -index 0020046..78926f8 100644 ---- a/hwdb/20-pci-vendor-model.hwdb -+++ b/hwdb/20-pci-vendor-model.hwdb -@@ -71141,6 +71141,12 @@ pci:v00001EEC* - pci:v00001EFB* - ID_VENDOR_FROM_DATABASE=Flexxon Pte Ltd - -+pci:v00001E3E* -+ ID_VENDOR_FROM_DATABASE=Iluvatar CoreX -+ -+pci:v00001E3Ed00000001* -+ ID_MODEL_FROM_DATABASE=Iluvatar BI-V100 -+ - pci:v00001FC0* - ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy - -diff --git a/hwdb/pci.ids b/hwdb/pci.ids -index 40ee143..d6661c7 100644 ---- a/hwdb/pci.ids -+++ b/hwdb/pci.ids -@@ -21543,6 +21543,8 @@ - 0003 alst4x - 1dfc JSC NT-COM - 1181 TDM 8 Port E1/T1/J1 Adapter -+1e3e Iluvatar CoreX -+ 0001 Iluvatar BI-V100 - # nee Tumsan Oy - 1fc0 Ascom (Finland) Oy - 0300 E2200 Dual E1/Rawpipe Card --- -2.27.0 - diff --git a/10012-seccomp-add-loongarch-support.patch b/10012-seccomp-add-loongarch-support.patch deleted file mode 100644 index 6aba34f..0000000 --- a/10012-seccomp-add-loongarch-support.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 4c7025f5198be3d055c0e5ad68d364a57e8a7dcc Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Thu, 22 Sep 2022 10:33:54 +0800 -Subject: [PATCH] seccomp: add loongarch support - ---- - src/shared/seccomp-util.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c -index c57c409..1eec0be 100644 ---- a/src/shared/seccomp-util.c -+++ b/src/shared/seccomp-util.c -@@ -42,6 +42,8 @@ const uint32_t seccomp_local_archs[] = { - SCMP_ARCH_AARCH64, /* native */ - #elif defined(__arm__) - SCMP_ARCH_ARM, -+#elif defined(__loongarch__) -+ SCMP_ARCH_LOONGARCH64, - #elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32 - SCMP_ARCH_MIPSEL, - SCMP_ARCH_MIPS, /* native */ -@@ -114,6 +116,8 @@ const char* seccomp_arch_to_string(uint32_t c) { - return "arm"; - case SCMP_ARCH_AARCH64: - return "arm64"; -+ case SCMP_ARCH_LOONGARCH64: -+ return "loongarch64"; - case SCMP_ARCH_MIPS: - return "mips"; - case SCMP_ARCH_MIPS64: -@@ -159,6 +163,8 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) { - *ret = SCMP_ARCH_ARM; - else if (streq(n, "arm64")) - *ret = SCMP_ARCH_AARCH64; -+ else if (streq(n, "loongarch64")) -+ *ret = SCMP_ARCH_LOONGARCH64; - else if (streq(n, "mips")) - *ret = SCMP_ARCH_MIPS; - else if (streq(n, "mips64")) -@@ -1206,7 +1212,7 @@ int seccomp_protect_sysctl(void) { - - log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch)); - -- if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64)) -+ if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64, SCMP_ARCH_LOONGARCH64)) - /* No _sysctl syscall */ - continue; - -@@ -1251,6 +1257,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { - case SCMP_ARCH_X32: - case SCMP_ARCH_ARM: - case SCMP_ARCH_AARCH64: -+ case SCMP_ARCH_LOONGARCH64: - case SCMP_ARCH_MIPSEL64N32: - case SCMP_ARCH_MIPS64N32: - case SCMP_ARCH_MIPSEL64: -@@ -1496,7 +1503,7 @@ static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp, - } - - /* For known architectures, check that syscalls are indeed defined or not. */ --#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) -+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch__) - assert_cc(SCMP_SYS(shmget) > 0); - assert_cc(SCMP_SYS(shmat) > 0); - assert_cc(SCMP_SYS(shmdt) > 0); -@@ -1543,13 +1550,14 @@ int seccomp_memory_deny_write_execute(void) { - case SCMP_ARCH_X86_64: - case SCMP_ARCH_X32: - case SCMP_ARCH_AARCH64: -+ case SCMP_ARCH_LOONGARCH64: - filter_syscall = SCMP_SYS(mmap); /* amd64, x32, and arm64 have only mmap */ - shmat_syscall = SCMP_SYS(shmat); - break; - - /* Please add more definitions here, if you port systemd to other architectures! */ - --#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) -+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__loongarch__) - #warning "Consider adding the right mmap() syscall definitions here!" - #endif - } -@@ -1573,13 +1581,13 @@ int seccomp_memory_deny_write_execute(void) { - if (r < 0) - continue; - } -- -+ if (!IN_SET(arch, SCMP_ARCH_LOONGARCH64)){ - r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(mprotect), - 1, - SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC)); - if (r < 0) - continue; -- -+ } - #ifdef __NR_pkey_mprotect - r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(pkey_mprotect), - 1, --- -2.27.0 - diff --git a/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch b/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch deleted file mode 100644 index f2eeed5..0000000 --- a/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 9f181efdd59bd3e9134cf94007953562ca8b57fa Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Sat, 15 Dec 2018 12:25:32 +0100 -Subject: [PATCH] fileio: when reading a full file into memory, refuse inner - NUL bytes - -Just some extra care to avoid any ambiguities in what we read. - -(cherry picked from commit beb90929913354eec50c3524086fe70d14f97e2f) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 25 +++++++++++++++++++------ - src/test/test-unit-file.c | 10 +++++----- - 2 files changed, 24 insertions(+), 11 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 733fb42463..9fef97ff0c 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -383,16 +383,20 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re - return 0; - } - --int read_full_stream(FILE *f, char **contents, size_t *size) { -+int read_full_stream( -+ FILE *f, -+ char **ret_contents, -+ size_t *ret_size) { -+ - _cleanup_free_ char *buf = NULL; - struct stat st; - size_t n, l; - int fd; - - assert(f); -- assert(contents); -+ assert(ret_contents); - -- n = LINE_MAX; -+ n = LINE_MAX; /* Start size */ - - fd = fileno(f); - if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's -@@ -448,11 +452,20 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { - n = MIN(n * 2, READ_FULL_BYTES_MAX); - } - -+ if (!ret_size) { -+ /* Safety check: if the caller doesn't want to know the size of what we just read it will rely on the -+ * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise -+ * there'd be ambiguity about what we just read. */ -+ -+ if (memchr(buf, 0, l)) -+ return -EBADMSG; -+ } -+ - buf[l] = 0; -- *contents = TAKE_PTR(buf); -+ *ret_contents = TAKE_PTR(buf); - -- if (size) -- *size = l; -+ if (ret_size) -+ *ret_size = l; - - return 0; - } -diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c -index 09b0179fa1..e64a27dd39 100644 ---- a/src/test/test-unit-file.c -+++ b/src/test/test-unit-file.c -@@ -532,7 +532,7 @@ static void test_load_env_file_1(void) { - - fd = mkostemp_safe(name); - assert_se(fd >= 0); -- assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1)); -+ assert_se(write(fd, env_file_1, strlen(env_file_1)) == strlen(env_file_1)); - - r = load_env_file(NULL, name, NULL, &data); - assert_se(r == 0); -@@ -554,7 +554,7 @@ static void test_load_env_file_2(void) { - - fd = mkostemp_safe(name); - assert_se(fd >= 0); -- assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2)); -+ assert_se(write(fd, env_file_2, strlen(env_file_2)) == strlen(env_file_2)); - - r = load_env_file(NULL, name, NULL, &data); - assert_se(r == 0); -@@ -571,7 +571,7 @@ static void test_load_env_file_3(void) { - - fd = mkostemp_safe(name); - assert_se(fd >= 0); -- assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3)); -+ assert_se(write(fd, env_file_3, strlen(env_file_3)) == strlen(env_file_3)); - - r = load_env_file(NULL, name, NULL, &data); - assert_se(r == 0); -@@ -586,7 +586,7 @@ static void test_load_env_file_4(void) { - - fd = mkostemp_safe(name); - assert_se(fd >= 0); -- assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4)); -+ assert_se(write(fd, env_file_4, strlen(env_file_4)) == strlen(env_file_4)); - - r = load_env_file(NULL, name, NULL, &data); - assert_se(r == 0); -@@ -605,7 +605,7 @@ static void test_load_env_file_5(void) { - - fd = mkostemp_safe(name); - assert_se(fd >= 0); -- assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); -+ assert_se(write(fd, env_file_5, strlen(env_file_5)) == strlen(env_file_5)); - - r = load_env_file(NULL, name, NULL, &data); - assert_se(r == 0); --- -2.39.1 - diff --git a/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch b/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch deleted file mode 100644 index c0ec4be..0000000 --- a/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 17037ec625fca9e9a473a33954d011065f0088e3 Mon Sep 17 00:00:00 2001 -From: Guorui Yu -Date: Fri, 23 Jun 2023 13:01:24 +0800 -Subject: [PATCH] util: introduce explicit_bzero_safe for explicit memset - -(cherry picked from commit f441ae81ef70e9bdfddbb9e0a276bbb8ca2151d4) - -Signed-off-by: Guorui Yu ---- - src/basic/util.c | 18 ++++++++++++++++++ - src/basic/util.h | 11 +++++++++++ - 2 files changed, 29 insertions(+) - -diff --git a/src/basic/util.c b/src/basic/util.c -index 548e3652cc..bdfaca4aed 100644 ---- a/src/basic/util.c -+++ b/src/basic/util.c -@@ -684,3 +684,21 @@ void disable_coredumps(void) { - if (r < 0) - log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); - } -+ -+#if !HAVE_EXPLICIT_BZERO -+/* -+ * The pointer to memset() is volatile so that compiler must de-reference the pointer and can't assume that -+ * it points to any function in particular (such as memset(), which it then might further "optimize"). This -+ * approach is inspired by openssl's crypto/mem_clr.c. -+ */ -+typedef void *(*memset_t)(void *,int,size_t); -+ -+static volatile memset_t memset_func = memset; -+ -+void* explicit_bzero_safe(void *p, size_t l) { -+ if (l > 0) -+ memset_func(p, '\0', l); -+ -+ return p; -+} -+#endif -diff --git a/src/basic/util.h b/src/basic/util.h -index 195f02cf5f..ab3314f82e 100644 ---- a/src/basic/util.h -+++ b/src/basic/util.h -@@ -240,3 +240,14 @@ int version(void); - int str_verscmp(const char *s1, const char *s2); - - void disable_coredumps(void); -+ -+#if HAVE_EXPLICIT_BZERO -+static inline void* explicit_bzero_safe(void *p, size_t l) { -+ if (l > 0) -+ explicit_bzero(p, l); -+ -+ return p; -+} -+#else -+void *explicit_bzero_safe(void *p, size_t l); -+#endif --- -2.39.1 - diff --git a/10015-util-introduce-erase_and_free-helper.patch b/10015-util-introduce-erase_and_free-helper.patch deleted file mode 100644 index 43c42fc..0000000 --- a/10015-util-introduce-erase_and_free-helper.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7c48fe64e3f1cdc61d9191d5e004d56d5244aa2c Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 8 Aug 2019 19:53:17 +0200 -Subject: [PATCH] util: introduce erase_and_free() helper - -(cherry picked from commit a20dda788d5a0f3b300e0d8bb34e45be335e2915) - -Signed-off-by: Guorui Yu ---- - src/basic/util.h | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/src/basic/util.h b/src/basic/util.h -index ab3314f82e..4f4877b6b0 100644 ---- a/src/basic/util.h -+++ b/src/basic/util.h -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -251,3 +252,20 @@ static inline void* explicit_bzero_safe(void *p, size_t l) { - #else - void *explicit_bzero_safe(void *p, size_t l); - #endif -+ -+static inline void* erase_and_free(void *p) { -+ size_t l; -+ -+ if (!p) -+ return NULL; -+ -+ l = malloc_usable_size(p); -+ explicit_bzero_safe(p, l); -+ free(p); -+ -+ return NULL; -+} -+ -+static inline void erase_and_freep(void *p) { -+ erase_and_free(*(void**) p); -+} --- -2.39.1 - diff --git a/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch b/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch deleted file mode 100644 index a37d579..0000000 --- a/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch +++ /dev/null @@ -1,207 +0,0 @@ -From bc781489901fc6447cbd27b8d33f4f4439d6a5db Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 8 Apr 2019 02:22:40 +0900 -Subject: [PATCH] util: introduce READ_FULL_FILE_SECURE flag for reading secure - data - -(cherry picked from commit e0721f97b05c0a5f782233711ea95c1e02ccba44) - -[Guorui Yu: include util.h for explicit_bzero_safe] -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 68 ++++++++++++++++++++++++++++++++-------------- - src/basic/fileio.h | 16 +++++++++-- - 2 files changed, 60 insertions(+), 24 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 9fef97ff0c..cf7c92ebc7 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -35,6 +35,7 @@ - #include "time-util.h" - #include "umask-util.h" - #include "utf8.h" -+#include "util.h" - - #define READ_FULL_BYTES_MAX (4U*1024U*1024U) - -@@ -383,26 +384,27 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re - return 0; - } - --int read_full_stream( -+int read_full_stream_full( - FILE *f, -+ ReadFullFileFlags flags, - char **ret_contents, - size_t *ret_size) { - - _cleanup_free_ char *buf = NULL; - struct stat st; -- size_t n, l; -- int fd; -+ size_t n, n_next, l; -+ int fd, r; - - assert(f); - assert(ret_contents); - -- n = LINE_MAX; /* Start size */ -+ n_next = LINE_MAX; /* Start size */ - - fd = fileno(f); - if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's - * optimize our buffering) */ - -- if (fstat(fileno(f), &st) < 0) -+ if (fstat(fd, &st) < 0) - return -errno; - - if (S_ISREG(st.st_mode)) { -@@ -415,27 +417,41 @@ int read_full_stream( - * to read here by one, so that the first read attempt already - * makes us notice the EOF. */ - if (st.st_size > 0) -- n = st.st_size + 1; -+ n_next = st.st_size + 1; - } - } - -- l = 0; -+ n = l = 0; - for (;;) { - char *t; - size_t k; - -- t = realloc(buf, n + 1); -- if (!t) -- return -ENOMEM; -+ if (flags & READ_FULL_FILE_SECURE) { -+ t = malloc(n_next + 1); -+ if (!t) { -+ r = -ENOMEM; -+ goto finalize; -+ } -+ memcpy_safe(t, buf, n); -+ explicit_bzero_safe(buf, n); -+ } else { -+ t = realloc(buf, n_next + 1); -+ if (!t) -+ return -ENOMEM; -+ } - - buf = t; -+ n = n_next; -+ - errno = 0; - k = fread(buf + l, 1, n - l, f); - if (k > 0) - l += k; - -- if (ferror(f)) -- return errno > 0 ? -errno : -EIO; -+ if (ferror(f)) { -+ r = errno > 0 ? -errno : -EIO; -+ goto finalize; -+ } - - if (feof(f)) - break; -@@ -446,10 +462,12 @@ int read_full_stream( - assert(l == n); - - /* Safety check */ -- if (n >= READ_FULL_BYTES_MAX) -- return -E2BIG; -+ if (n >= READ_FULL_BYTES_MAX) { -+ r = -E2BIG; -+ goto finalize; -+ } - -- n = MIN(n * 2, READ_FULL_BYTES_MAX); -+ n_next = MIN(n * 2, READ_FULL_BYTES_MAX); - } - - if (!ret_size) { -@@ -457,8 +475,10 @@ int read_full_stream( - * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise - * there'd be ambiguity about what we just read. */ - -- if (memchr(buf, 0, l)) -- return -EBADMSG; -+ if (memchr(buf, 0, l)) { -+ r = -EBADMSG; -+ goto finalize; -+ } - } - - buf[l] = 0; -@@ -468,21 +488,27 @@ int read_full_stream( - *ret_size = l; - - return 0; -+ -+finalize: -+ if (flags & READ_FULL_FILE_SECURE) -+ explicit_bzero_safe(buf, n); -+ -+ return r; - } - --int read_full_file(const char *fn, char **contents, size_t *size) { -+int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { - _cleanup_fclose_ FILE *f = NULL; - -- assert(fn); -+ assert(filename); - assert(contents); - -- f = fopen(fn, "re"); -+ f = fopen(filename, "re"); - if (!f) - return -errno; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - -- return read_full_stream(f, contents, size); -+ return read_full_stream_full(f, flags, contents, size); - } - - static int parse_env_file_internal( -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index c6ad375b8d..06649ef7e6 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -24,6 +24,10 @@ typedef enum { - - } WriteStringFileFlags; - -+typedef enum { -+ READ_FULL_FILE_SECURE = 1 << 0, -+} ReadFullFileFlags; -+ - int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); - static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { - return write_string_stream_ts(f, line, flags, NULL); -@@ -35,9 +39,15 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin - - int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); - --int read_one_line_file(const char *fn, char **line); --int read_full_file(const char *fn, char **contents, size_t *size); --int read_full_stream(FILE *f, char **contents, size_t *size); -+int read_one_line_file(const char *filename, char **line); -+int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); -+static inline int read_full_file(const char *filename, char **contents, size_t *size) { -+ return read_full_file_full(filename, 0, contents, size); -+} -+int read_full_stream_full(FILE *f, ReadFullFileFlags flags, char **contents, size_t *size); -+static inline int read_full_stream(FILE *f, char **contents, size_t *size) { -+ return read_full_stream_full(f, 0, contents, size); -+} - int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); - - int verify_file(const char *fn, const char *blob, bool accept_extra_nl); --- -2.39.1 - diff --git a/10017-fileio-introduce-warn_file_is_world_accessible.patch b/10017-fileio-introduce-warn_file_is_world_accessible.patch deleted file mode 100644 index 02f9518..0000000 --- a/10017-fileio-introduce-warn_file_is_world_accessible.patch +++ /dev/null @@ -1,67 +0,0 @@ -From e4c4f0bc712e43776c4f58712f47260711607098 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 8 Apr 2019 03:48:30 +0900 -Subject: [PATCH] fileio: introduce warn_file_is_world_accessible() - -(cherry picked from commit fc0895034d4811e8c6b263c0d902b31535613d76) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 25 +++++++++++++++++++++++++ - src/basic/fileio.h | 3 +++ - 2 files changed, 28 insertions(+) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index cf7c92ebc7..2e74aac554 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -1797,3 +1797,28 @@ int read_line(FILE *f, size_t limit, char **ret) { - - return (int) count; - } -+ -+int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line) { -+ struct stat _st; -+ -+ if (!filename) -+ return 0; -+ -+ if (!st) { -+ if (stat(filename, &_st) < 0) -+ return -errno; -+ st = &_st; -+ } -+ -+ if ((st->st_mode & S_IRWXO) == 0) -+ return 0; -+ -+ if (unit) -+ log_syntax(unit, LOG_WARNING, filename, line, 0, -+ "%s has %04o mode that is too permissive, please adjust the access mode.", -+ filename, st->st_mode & 07777); -+ else -+ log_warning("%s has %04o mode that is too permissive, please adjust the access mode.", -+ filename, st->st_mode & 07777); -+ return 0; -+} -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 06649ef7e6..2c9ce4355b 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - - #include "macro.h" -@@ -105,3 +106,5 @@ int read_nul_string(FILE *f, char **ret); - int mkdtemp_malloc(const char *template, char **ret); - - int read_line(FILE *f, size_t limit, char **ret); -+ -+int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line); --- -2.39.1 - diff --git a/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch b/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch deleted file mode 100644 index af813a5..0000000 --- a/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0dbf69ccdfa7b1f99935c3932445fbfa16dbbe75 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 8 Apr 2019 14:15:10 +0900 -Subject: [PATCH] fileio: read_full_file_full() also warns when file is world - readable and secure flag is set - -(cherry picked from commit 65dcd394d8223bc6bc194f3fe5bd70fed9d9a4fe) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 6 +++++- - src/basic/fileio.h | 4 ++-- - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 2e74aac554..3abeb0d7f4 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -386,6 +386,7 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re - - int read_full_stream_full( - FILE *f, -+ const char *filename, - ReadFullFileFlags flags, - char **ret_contents, - size_t *ret_size) { -@@ -418,6 +419,9 @@ int read_full_stream_full( - * makes us notice the EOF. */ - if (st.st_size > 0) - n_next = st.st_size + 1; -+ -+ if (flags & READ_FULL_FILE_SECURE) -+ (void) warn_file_is_world_accessible(filename, &st, NULL, 0); - } - } - -@@ -508,7 +512,7 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - -- return read_full_stream_full(f, flags, contents, size); -+ return read_full_stream_full(f, filename, flags, contents, size); - } - - static int parse_env_file_internal( -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 2c9ce4355b..3e572dc0de 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -45,9 +45,9 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co - static inline int read_full_file(const char *filename, char **contents, size_t *size) { - return read_full_file_full(filename, 0, contents, size); - } --int read_full_stream_full(FILE *f, ReadFullFileFlags flags, char **contents, size_t *size); -+int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); - static inline int read_full_stream(FILE *f, char **contents, size_t *size) { -- return read_full_stream_full(f, 0, contents, size); -+ return read_full_stream_full(f, NULL, 0, contents, size); - } - int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); - --- -2.39.1 - diff --git a/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch b/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch deleted file mode 100644 index e434089..0000000 --- a/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 14e0760c251fd5fc51731f7b58079c73f5055d64 Mon Sep 17 00:00:00 2001 -From: Benjamin Robin -Date: Sun, 14 Apr 2019 17:21:27 +0200 -Subject: [PATCH] basic/fileio: Fix memory leak if READ_FULL_FILE_SECURE flag - is used - -The memory leak introduced in #12223 (15f8f02) - -(cherry picked from commit 315a51982af2d480de9f7539346f30425e37a01e) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 3abeb0d7f4..bb804e3afa 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -438,6 +438,7 @@ int read_full_stream_full( - } - memcpy_safe(t, buf, n); - explicit_bzero_safe(buf, n); -+ buf = mfree(buf); - } else { - t = realloc(buf, n_next + 1); - if (!t) --- -2.39.1 - diff --git a/10020-fileio-add-explicit-flag-for-generating-world-execu.patch b/10020-fileio-add-explicit-flag-for-generating-world-execu.patch deleted file mode 100644 index 1a93b5a..0000000 --- a/10020-fileio-add-explicit-flag-for-generating-world-execu.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 1e0dcd6fa1abea9c561f46556f7f7561b2a46e62 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Fri, 17 Jul 2020 11:53:22 +0200 -Subject: [PATCH] fileio: add explicit flag for generating world executable - warning when reading file - -(cherry picked from commit 684aa979f1c4ce5f75ccdc131f32fc0434999918) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 2 +- - src/basic/fileio.h | 3 ++- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index bb804e3afa..833c55b030 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -420,7 +420,7 @@ int read_full_stream_full( - if (st.st_size > 0) - n_next = st.st_size + 1; - -- if (flags & READ_FULL_FILE_SECURE) -+ if (flags & READ_FULL_FILE_WARN_WORLD_READABLE) - (void) warn_file_is_world_accessible(filename, &st, NULL, 0); - } - } -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 3e572dc0de..be10ac77b6 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -26,7 +26,8 @@ typedef enum { - } WriteStringFileFlags; - - typedef enum { -- READ_FULL_FILE_SECURE = 1 << 0, -+ READ_FULL_FILE_SECURE = 1 << 0, -+ READ_FULL_FILE_WARN_WORLD_READABLE = 1 << 3, - } ReadFullFileFlags; - - int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); --- -2.39.1 - diff --git a/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch b/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch deleted file mode 100644 index f6dc153..0000000 --- a/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 3f4ca11498028756ebde239ae469c0f88e5d3ecc Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 8 Jan 2019 18:29:36 +0100 -Subject: [PATCH] fileio: add 'dir_fd' parameter to read_full_file_full() - -Let's introduce an "at" version of read_full_file(). - -(cherry picked from commit f6be4db4530b7cfea191227c141343a4fb10d4c6) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 84 +++++++++++++++++++++++++++++++++++++++++++--- - src/basic/fileio.h | 5 +-- - 2 files changed, 83 insertions(+), 6 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 833c55b030..d7da834a74 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -501,15 +501,91 @@ finalize: - return r; - } - --int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { -+static int mode_to_flags(const char *mode) { -+ const char *p; -+ int flags; -+ -+ if ((p = startswith(mode, "r+"))) -+ flags = O_RDWR; -+ else if ((p = startswith(mode, "r"))) -+ flags = O_RDONLY; -+ else if ((p = startswith(mode, "w+"))) -+ flags = O_RDWR|O_CREAT|O_TRUNC; -+ else if ((p = startswith(mode, "w"))) -+ flags = O_WRONLY|O_CREAT|O_TRUNC; -+ else if ((p = startswith(mode, "a+"))) -+ flags = O_RDWR|O_CREAT|O_APPEND; -+ else if ((p = startswith(mode, "a"))) -+ flags = O_WRONLY|O_CREAT|O_APPEND; -+ else -+ return -EINVAL; -+ -+ for (; *p != 0; p++) { -+ -+ switch (*p) { -+ -+ case 'e': -+ flags |= O_CLOEXEC; -+ break; -+ -+ case 'x': -+ flags |= O_EXCL; -+ break; -+ -+ case 'm': -+ /* ignore this here, fdopen() might care later though */ -+ break; -+ -+ case 'c': /* not sure what to do about this one */ -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return flags; -+} -+ -+static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **ret) { -+ FILE *f; -+ -+ /* A combination of fopen() with openat() */ -+ -+ if (dir_fd == AT_FDCWD && flags == 0) { -+ f = fopen(path, mode); -+ if (!f) -+ return -errno; -+ } else { -+ int fd, mode_flags; -+ -+ mode_flags = mode_to_flags(mode); -+ if (mode_flags < 0) -+ return mode_flags; -+ -+ fd = openat(dir_fd, path, mode_flags | flags); -+ if (fd < 0) -+ return -errno; -+ -+ f = fdopen(fd, mode); -+ if (!f) { -+ safe_close(fd); -+ return -errno; -+ } -+ } -+ -+ *ret = f; -+ return 0; -+} -+ -+int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { - _cleanup_fclose_ FILE *f = NULL; -+ int r; - - assert(filename); - assert(contents); - -- f = fopen(filename, "re"); -- if (!f) -- return -errno; -+ r = xfopenat(dir_fd, filename, "re", 0, &f); -+ if (r < 0) -+ return r; - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index be10ac77b6..916ddc5e47 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - - #include "macro.h" -@@ -42,9 +43,9 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin - int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); - - int read_one_line_file(const char *filename, char **line); --int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); -+int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); - static inline int read_full_file(const char *filename, char **contents, size_t *size) { -- return read_full_file_full(filename, 0, contents, size); -+ return read_full_file_full(AT_FDCWD, filename, 0, contents, size); - } - int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); - static inline int read_full_stream(FILE *f, char **contents, size_t *size) { --- -2.39.1 - diff --git a/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch b/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch deleted file mode 100644 index bb392bc..0000000 --- a/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 054669a4cc4897792b6c209fd55ab1fc1d7b9bd5 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Fri, 17 Jul 2020 12:26:01 +0200 -Subject: [PATCH] fileio: add support for read_full_file() on AF_UNIX stream - sockets - -Optionally, teach read_full_file() the ability to connect to an AF_UNIX -socket if the specified path points to one. - -(cherry picked from commit 412b888ec803cdf96fb1d005bb245d20abdb8f2e) - -[Guorui Yu: Adds sockaddr_un_set_path function to socket-util.{c,h}] -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 62 +++++++++++++++++++++++++++++++++++------ - src/basic/fileio.h | 1 + - src/basic/socket-util.c | 42 ++++++++++++++++++++++++++++ - src/basic/socket-util.h | 1 + - src/test/test-fileio.c | 50 +++++++++++++++++++++++++++++++++ - 5 files changed, 147 insertions(+), 9 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index d7da834a74..9cb0a2bd28 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -27,6 +27,7 @@ - #include "missing.h" - #include "parse-util.h" - #include "path-util.h" -+#include "socket-util.h" - #include "process-util.h" - #include "random-util.h" - #include "stdio-util.h" -@@ -450,21 +451,18 @@ int read_full_stream_full( - - errno = 0; - k = fread(buf + l, 1, n - l, f); -- if (k > 0) -- l += k; -+ -+ assert(k <= n - l); -+ l += k; - - if (ferror(f)) { - r = errno > 0 ? -errno : -EIO; - goto finalize; - } -- - if (feof(f)) - break; - -- /* We aren't expecting fread() to return a short read outside -- * of (error && eof), assert buffer is full and enlarge buffer. -- */ -- assert(l == n); -+ assert(k > 0); /* we can't have read zero bytes because that would have been EOF */ - - /* Safety check */ - if (n >= READ_FULL_BYTES_MAX) { -@@ -584,8 +582,54 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag - assert(contents); - - r = xfopenat(dir_fd, filename, "re", 0, &f); -- if (r < 0) -- return r; -+ if (r < 0) { -+ _cleanup_close_ int dfd = -1, sk = -1; -+ union sockaddr_union sa; -+ -+ /* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */ -+ if (r != -ENXIO) -+ return r; -+ -+ /* If this is enabled, let's try to connect to it */ -+ if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET)) -+ return -ENXIO; -+ -+ if (dir_fd == AT_FDCWD) -+ r = sockaddr_un_set_path(&sa.un, filename); -+ else { -+ char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; -+ -+ /* If we shall operate relative to some directory, then let's use O_PATH first to -+ * open the socket inode, and then connect to it via /proc/self/fd/. We have to do -+ * this since there's not connectat() that takes a directory fd as first arg. */ -+ -+ dfd = openat(dir_fd, filename, O_PATH|O_CLOEXEC); -+ if (dfd < 0) -+ return -errno; -+ -+ xsprintf(procfs_path, "/proc/self/fd/%i", dfd); -+ r = sockaddr_un_set_path(&sa.un, procfs_path); -+ } -+ if (r < 0) -+ return r; -+ -+ sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); -+ if (sk < 0) -+ return -errno; -+ -+ if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) -+ return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is -+ * not a socket after all */ -+ -+ if (shutdown(sk, SHUT_WR) < 0) -+ return -errno; -+ -+ f = fdopen(sk, "r"); -+ if (!f) -+ return -errno; -+ -+ TAKE_FD(sk); -+ } - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 916ddc5e47..1a16e0fd13 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -29,6 +29,7 @@ typedef enum { - typedef enum { - READ_FULL_FILE_SECURE = 1 << 0, - READ_FULL_FILE_WARN_WORLD_READABLE = 1 << 3, -+ READ_FULL_FILE_CONNECT_SOCKET = 1 << 4, - } ReadFullFileFlags; - - int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); -diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c -index 7f8066123b..427c8b89bb 100644 ---- a/src/basic/socket-util.c -+++ b/src/basic/socket-util.c -@@ -1253,6 +1253,48 @@ int socket_ioctl_fd(void) { - return fd; - } - -+int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) { -+ size_t l; -+ -+ assert(ret); -+ assert(path); -+ -+ /* Initialize ret->sun_path from the specified argument. This will interpret paths starting with '@' as -+ * abstract namespace sockets, and those starting with '/' as regular filesystem sockets. It won't accept -+ * anything else (i.e. no relative paths), to avoid ambiguities. Note that this function cannot be used to -+ * reference paths in the abstract namespace that include NUL bytes in the name. */ -+ -+ l = strlen(path); -+ if (l < 2) -+ return -EINVAL; -+ if (!IN_SET(path[0], '/', '@')) -+ return -EINVAL; -+ -+ /* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than -+ * the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket -+ * addresses!), which the kernel doesn't. We do this to reduce chance of incompatibility with other apps that -+ * do not expect non-NUL terminated file system path*/ -+ if (l+1 > sizeof(ret->sun_path)) -+ return -EINVAL; -+ -+ *ret = (struct sockaddr_un) { -+ .sun_family = AF_UNIX, -+ }; -+ -+ if (path[0] == '@') { -+ /* Abstract namespace socket */ -+ memcpy(ret->sun_path + 1, path + 1, l); /* copy *with* trailing NUL byte */ -+ return (int) (offsetof(struct sockaddr_un, sun_path) + l); /* 🔥 *don't* 🔥 include trailing NUL in size */ -+ -+ } else { -+ assert(path[0] == '/'); -+ -+ /* File system socket */ -+ memcpy(ret->sun_path, path, l + 1); /* copy *with* trailing NUL byte */ -+ return (int) (offsetof(struct sockaddr_un, sun_path) + l + 1); /* include trailing NUL in size */ -+ } -+} -+ - int socket_pass_pktinfo(int fd, bool b) { - int af; - socklen_t sl = sizeof(af); -diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h -index 30baba6c03..36edc58caf 100644 ---- a/src/basic/socket-util.h -+++ b/src/basic/socket-util.h -@@ -186,6 +186,7 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng - }) - - int socket_ioctl_fd(void); -+int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path); - - static inline int setsockopt_int(int fd, int level, int optname, int value) { - if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0) -diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c -index 14ba075144..82b7cb1242 100644 ---- a/src/test/test-fileio.c -+++ b/src/test/test-fileio.c -@@ -14,6 +14,8 @@ - #include "io-util.h" - #include "parse-util.h" - #include "process-util.h" -+#include "rm-rf.h" -+#include "socket-util.h" - #include "string-util.h" - #include "strv.h" - #include "util.h" -@@ -709,6 +711,53 @@ static void test_read_line3(void) { - assert_se(read_line(f, LINE_MAX, NULL) == 0); - } - -+static void test_read_full_file_socket(void) { -+ _cleanup_(rm_rf_physical_and_freep) char *z = NULL; -+ _cleanup_close_ int listener = -1; -+ _cleanup_free_ char *data = NULL; -+ union sockaddr_union sa; -+ const char *j; -+ size_t size; -+ pid_t pid; -+ int r; -+ -+ log_info("/* %s */", __func__); -+ -+ listener = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); -+ assert_se(listener >= 0); -+ -+ assert_se(mkdtemp_malloc(NULL, &z) >= 0); -+ j = strjoina(z, "/socket"); -+ -+ assert_se(sockaddr_un_set_path(&sa.un, j) >= 0); -+ -+ assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0); -+ assert_se(listen(listener, 1) >= 0); -+ -+ r = safe_fork("(server)", FORK_DEATHSIG|FORK_LOG, &pid); -+ assert_se(r >= 0); -+ if (r == 0) { -+ _cleanup_close_ int rfd = -1; -+ /* child */ -+ -+ rfd = accept4(listener, NULL, 0, SOCK_CLOEXEC); -+ assert_se(rfd >= 0); -+ -+#define TEST_STR "This is a test\nreally." -+ -+ assert_se(write(rfd, TEST_STR, strlen(TEST_STR)) == strlen(TEST_STR)); -+ _exit(EXIT_SUCCESS); -+ } -+ -+ assert_se(read_full_file_full(AT_FDCWD, j, 0, &data, &size) == -ENXIO); -+ assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, &data, &size) >= 0); -+ assert_se(size == strlen(TEST_STR)); -+ assert_se(streq(data, TEST_STR)); -+ -+ assert_se(wait_for_terminate_and_check("(server)", pid, WAIT_LOG) >= 0); -+#undef TEST_STR -+} -+ - int main(int argc, char *argv[]) { - log_set_max_level(LOG_DEBUG); - log_parse_environment(); -@@ -733,6 +782,7 @@ int main(int argc, char *argv[]) { - test_read_line(); - test_read_line2(); - test_read_line3(); -+ test_read_full_file_socket(); - - return 0; - } --- -2.39.1 - diff --git a/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch b/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch deleted file mode 100644 index 2edc538..0000000 --- a/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 0717de25e6508b10ea034fa1b96675f18100ac01 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Mon, 2 Nov 2020 12:07:51 +0100 -Subject: [PATCH] fileio: beef up READ_FULL_FILE_CONNECT_SOCKET to allow - setting sender socket name - -This beefs up the READ_FULL_FILE_CONNECT_SOCKET logic of -read_full_file_full() a bit: when used a sender socket name may be -specified. If specified as NULL behaviour is as before: the client -socket name is picked by the kernel. But if specified as non-NULL the -client can pick a socket name to use when connecting. This is useful to -communicate a minimal amount of metainformation from client to server, -outside of the transport payload. - -Specifically, these beefs up the service credential logic to pass an -abstract AF_UNIX socket name as client socket name when connecting via -READ_FULL_FILE_CONNECT_SOCKET, that includes the requesting unit name -and the eventual credential name. This allows servers implementing the -trivial credential socket logic to distinguish clients: via a simple -getpeername() it can be determined which unit is requesting a -credential, and which credential specifically. - -Example: with this patch in place, in a unit file "waldo.service" a -configuration line like the following: - - LoadCredential=foo:/run/quux/creds.sock - -will result in a connection to the AF_UNIX socket /run/quux/creds.sock, -originating from an abstract namespace AF_UNIX socket: - - @$RANDOM/unit/waldo.service/foo - -(The $RANDOM is replaced by some randomized string. This is included in -the socket name order to avoid namespace squatting issues: the abstract -socket namespace is open to unprivileged users after all, and care needs -to be taken not to use guessable names) - -The services listening on the /run/quux/creds.sock socket may thus -easily retrieve the name of the unit the credential is requested for -plus the credential name, via a simpler getpeername(), discarding the -random preifx and the /unit/ string. - -This logic uses "/" as separator between the fields, since both unit -names and credential names appear in the file system, and thus are -designed to use "/" as outer separators. Given that it's a good safe -choice to use as separators here, too avoid any conflicts. - -This is a minimal patch only: the new logic is used only for the unit -file credential logic. For other places where we use -READ_FULL_FILE_CONNECT_SOCKET it is probably a good idea to use this -scheme too, but this should be done carefully in later patches, since -the socket names become API that way, and we should determine the right -amount of info to pass over. - -(cherry picked from commit 142e9756c98c69cdd5d03df4028700acb5739f72) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 22 +++++++++++++++++++++- - src/basic/fileio.h | 4 ++-- - src/test/test-fileio.c | 19 ++++++++++++++++--- - 3 files changed, 39 insertions(+), 6 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 9cb0a2bd28..35eaa3c1c7 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -574,7 +574,13 @@ static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, F - return 0; - } - --int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { -+int read_full_file_full( -+ int dir_fd, -+ const char *filename, -+ ReadFullFileFlags flags, -+ const char *bind_name, -+ char **contents, size_t *size) { -+ - _cleanup_fclose_ FILE *f = NULL; - int r; - -@@ -617,6 +623,20 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag - if (sk < 0) - return -errno; - -+ if (bind_name) { -+ /* If the caller specified a socket name to bind to, do so before connecting. This is -+ * useful to communicate some minor, short meta-information token from the client to -+ * the server. */ -+ union sockaddr_union bsa; -+ -+ r = sockaddr_un_set_path(&bsa.un, bind_name); -+ if (r < 0) -+ return r; -+ -+ if (bind(sk, &bsa.sa, r) < 0) -+ return r; -+ } -+ - if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) - return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is - * not a socket after all */ -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 1a16e0fd13..82897e209c 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -44,9 +44,9 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin - int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); - - int read_one_line_file(const char *filename, char **line); --int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); -+int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, const char *bind_name, char **contents, size_t *size); - static inline int read_full_file(const char *filename, char **contents, size_t *size) { -- return read_full_file_full(AT_FDCWD, filename, 0, contents, size); -+ return read_full_file_full(AT_FDCWD, filename, 0, NULL, contents, size); - } - int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); - static inline int read_full_stream(FILE *f, char **contents, size_t *size) { -diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c -index 82b7cb1242..5ec70eec14 100644 ---- a/src/test/test-fileio.c -+++ b/src/test/test-fileio.c -@@ -14,6 +14,7 @@ - #include "io-util.h" - #include "parse-util.h" - #include "process-util.h" -+#include "random-util.h" - #include "rm-rf.h" - #include "socket-util.h" - #include "string-util.h" -@@ -714,7 +715,7 @@ static void test_read_line3(void) { - static void test_read_full_file_socket(void) { - _cleanup_(rm_rf_physical_and_freep) char *z = NULL; - _cleanup_close_ int listener = -1; -- _cleanup_free_ char *data = NULL; -+ _cleanup_free_ char *data = NULL, *clientname = NULL; - union sockaddr_union sa; - const char *j; - size_t size; -@@ -734,23 +735,35 @@ static void test_read_full_file_socket(void) { - assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0); - assert_se(listen(listener, 1) >= 0); - -+ /* Bind the *client* socket to some randomized name, to verify that this works correctly. */ -+ assert_se(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()) >= 0); -+ - r = safe_fork("(server)", FORK_DEATHSIG|FORK_LOG, &pid); - assert_se(r >= 0); - if (r == 0) { -+ union sockaddr_union peer = {}; -+ socklen_t peerlen = sizeof(peer); - _cleanup_close_ int rfd = -1; - /* child */ - - rfd = accept4(listener, NULL, 0, SOCK_CLOEXEC); - assert_se(rfd >= 0); - -+ assert_se(getpeername(rfd, &peer.sa, &peerlen) >= 0); -+ -+ assert_se(peer.un.sun_family == AF_UNIX); -+ assert_se(peerlen > offsetof(struct sockaddr_un, sun_path)); -+ assert_se(peer.un.sun_path[0] == 0); -+ assert_se(streq(peer.un.sun_path + 1, clientname + 1)); -+ - #define TEST_STR "This is a test\nreally." - - assert_se(write(rfd, TEST_STR, strlen(TEST_STR)) == strlen(TEST_STR)); - _exit(EXIT_SUCCESS); - } - -- assert_se(read_full_file_full(AT_FDCWD, j, 0, &data, &size) == -ENXIO); -- assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, &data, &size) >= 0); -+ assert_se(read_full_file_full(AT_FDCWD, j, 0, NULL, &data, &size) == -ENXIO); -+ assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); - assert_se(size == strlen(TEST_STR)); - assert_se(streq(data, TEST_STR)); - --- -2.39.1 - diff --git a/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch b/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch deleted file mode 100644 index 08e8f40..0000000 --- a/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 5be0e8a2c3e683c195fd872979d6e5741c80d13f Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 4 Nov 2020 20:25:06 +0100 -Subject: [PATCH] fileio: teach read_full_file_full() to read from offset/with - maximum size - -(cherry picked from commit 7399b3f8083b65db4cb9acb17e4b5c897ba7946d) - -Signed-off-by: Guorui Yu ---- - src/basic/fileio.c | 60 ++++++++++++++++++++++++++++++------------ - src/basic/fileio.h | 12 ++++----- - src/test/test-fileio.c | 49 ++++++++++++++++++++++++++++++++-- - 3 files changed, 96 insertions(+), 25 deletions(-) - -diff --git a/src/basic/fileio.c b/src/basic/fileio.c -index 35eaa3c1c7..c14f9797bd 100644 ---- a/src/basic/fileio.c -+++ b/src/basic/fileio.c -@@ -388,44 +388,58 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re - int read_full_stream_full( - FILE *f, - const char *filename, -+ uint64_t offset, -+ size_t size, - ReadFullFileFlags flags, - char **ret_contents, - size_t *ret_size) { - - _cleanup_free_ char *buf = NULL; -- struct stat st; - size_t n, n_next, l; - int fd, r; - - assert(f); - assert(ret_contents); - -- n_next = LINE_MAX; /* Start size */ -+ if (offset != UINT64_MAX && offset > LONG_MAX) -+ return -ERANGE; -+ -+ n_next = size != SIZE_MAX ? size : LINE_MAX; /* Start size */ - - fd = fileno(f); -- if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's -- * optimize our buffering) */ -+ if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see -+ * fmemopen()), let's optimize our buffering */ -+ struct stat st; - - if (fstat(fd, &st) < 0) - return -errno; - - if (S_ISREG(st.st_mode)) { -- -- /* Safety check */ -- if (st.st_size > READ_FULL_BYTES_MAX) -- return -E2BIG; -- -- /* Start with the right file size. Note that we increase the size -- * to read here by one, so that the first read attempt already -- * makes us notice the EOF. */ -- if (st.st_size > 0) -- n_next = st.st_size + 1; -+ if (size == SIZE_MAX) { -+ uint64_t rsize = -+ LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset); -+ -+ /* Safety check */ -+ if (rsize > READ_FULL_BYTES_MAX) -+ return -E2BIG; -+ -+ /* Start with the right file size. Note that we increase the size to read -+ * here by one, so that the first read attempt already makes us notice the -+ * EOF. If the reported size of the file is zero, we avoid this logic -+ * however, since quite likely it might be a virtual file in procfs that all -+ * report a zero file size. */ -+ if (st.st_size > 0) -+ n_next = rsize + 1; -+ } - - if (flags & READ_FULL_FILE_WARN_WORLD_READABLE) - (void) warn_file_is_world_accessible(filename, &st, NULL, 0); - } - } - -+ if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0) -+ return -errno; -+ - n = l = 0; - for (;;) { - char *t; -@@ -462,6 +476,11 @@ int read_full_stream_full( - if (feof(f)) - break; - -+ if (size != SIZE_MAX) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */ -+ assert(l == size); -+ break; -+ } -+ - assert(k > 0); /* we can't have read zero bytes because that would have been EOF */ - - /* Safety check */ -@@ -577,15 +596,18 @@ static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, F - int read_full_file_full( - int dir_fd, - const char *filename, -+ uint64_t offset, -+ size_t size, - ReadFullFileFlags flags, - const char *bind_name, -- char **contents, size_t *size) { -+ char **ret_contents, -+ size_t *ret_size) { - - _cleanup_fclose_ FILE *f = NULL; - int r; - - assert(filename); -- assert(contents); -+ assert(ret_contents); - - r = xfopenat(dir_fd, filename, "re", 0, &f); - if (r < 0) { -@@ -600,6 +622,10 @@ int read_full_file_full( - if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET)) - return -ENXIO; - -+ /* Seeking is not supported on AF_UNIX sockets */ -+ if (offset != UINT64_MAX) -+ return -ESPIPE; -+ - if (dir_fd == AT_FDCWD) - r = sockaddr_un_set_path(&sa.un, filename); - else { -@@ -653,7 +679,7 @@ int read_full_file_full( - - (void) __fsetlocking(f, FSETLOCKING_BYCALLER); - -- return read_full_stream_full(f, filename, flags, contents, size); -+ return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size); - } - - static int parse_env_file_internal( -diff --git a/src/basic/fileio.h b/src/basic/fileio.h -index 82897e209c..03150ce776 100644 ---- a/src/basic/fileio.h -+++ b/src/basic/fileio.h -@@ -44,13 +44,13 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin - int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); - - int read_one_line_file(const char *filename, char **line); --int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, const char *bind_name, char **contents, size_t *size); --static inline int read_full_file(const char *filename, char **contents, size_t *size) { -- return read_full_file_full(AT_FDCWD, filename, 0, NULL, contents, size); -+int read_full_file_full(int dir_fd, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, const char *bind_name, char **ret_contents, size_t *ret_size); -+static inline int read_full_file(const char *filename, char **ret_contents, size_t *ret_size) { -+ return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size); - } --int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); --static inline int read_full_stream(FILE *f, char **contents, size_t *size) { -- return read_full_stream_full(f, NULL, 0, contents, size); -+int read_full_stream_full(FILE *f, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, char **ret_contents, size_t *ret_size); -+static inline int read_full_stream(FILE *f, char **ret_contents, size_t *ret_size) { -+ return read_full_stream_full(f, NULL, UINT64_MAX, SIZE_MAX, 0, ret_contents, ret_size); - } - int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); - -diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c -index 5ec70eec14..5d0006149b 100644 ---- a/src/test/test-fileio.c -+++ b/src/test/test-fileio.c -@@ -762,8 +762,8 @@ static void test_read_full_file_socket(void) { - _exit(EXIT_SUCCESS); - } - -- assert_se(read_full_file_full(AT_FDCWD, j, 0, NULL, &data, &size) == -ENXIO); -- assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); -+ assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO); -+ assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); - assert_se(size == strlen(TEST_STR)); - assert_se(streq(data, TEST_STR)); - -@@ -771,6 +771,50 @@ static void test_read_full_file_socket(void) { - #undef TEST_STR - } - -+static void test_read_full_file_offset_size(void) { -+ _cleanup_fclose_ FILE *f = NULL; -+ _cleanup_(unlink_and_freep) char *fn = NULL; -+ _cleanup_free_ char *rbuf = NULL; -+ size_t rbuf_size; -+ uint8_t buf[4711]; -+ -+ random_bytes(buf, sizeof(buf)); -+ -+ assert_se(tempfn_random_child(NULL, NULL, &fn) >= 0); -+ assert_se(f = fopen(fn, "we")); -+ assert_se(fwrite(buf, 1, sizeof(buf), f) == sizeof(buf)); -+ assert_se(fflush_and_check(f) >= 0); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, SIZE_MAX, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == sizeof(buf)); -+ assert_se(memcmp(buf, rbuf, rbuf_size) == 0); -+ rbuf = mfree(rbuf); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, 128, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == 128); -+ assert_se(memcmp(buf, rbuf, rbuf_size) == 0); -+ rbuf = mfree(rbuf); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, 1234, SIZE_MAX, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == sizeof(buf) - 1234); -+ assert_se(memcmp(buf + 1234, rbuf, rbuf_size) == 0); -+ rbuf = mfree(rbuf); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, 2345, 777, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == 777); -+ assert_se(memcmp(buf + 2345, rbuf, rbuf_size) == 0); -+ rbuf = mfree(rbuf); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, 4700, 20, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == 11); -+ assert_se(memcmp(buf + 4700, rbuf, rbuf_size) == 0); -+ rbuf = mfree(rbuf); -+ -+ assert_se(read_full_file_full(AT_FDCWD, fn, 10000, 99, 0, NULL, &rbuf, &rbuf_size) >= 0); -+ assert_se(rbuf_size == 0); -+ rbuf = mfree(rbuf); -+} -+ - int main(int argc, char *argv[]) { - log_set_max_level(LOG_DEBUG); - log_parse_environment(); -@@ -796,6 +840,7 @@ int main(int argc, char *argv[]) { - test_read_line2(); - test_read_line3(); - test_read_full_file_socket(); -+ test_read_full_file_offset_size(); - - return 0; - } --- -2.39.1 - diff --git a/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch b/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch deleted file mode 100644 index bb66170..0000000 --- a/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 8ef03861b75cf0a70511760c395cb4bd228c37b9 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 4 Nov 2020 17:24:53 +0100 -Subject: [PATCH] cryptsetup: port cryptsetup's main key file logic over to - read_full_file_full() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously, we'd load the file with libcryptsetup's calls. Let's do that -in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET, -i.e. read in keys via AF_UNIX sockets, so that people can plug key -providers into our logic. - -This provides functionality similar to Debian's keyscript= crypttab -option (see → #3007), as it allows key scripts to be run as socket -activated services, that have stdout connected to the activated socket. -In contrast to traditional keyscript= support this logic runs stuff out -of process however, which is beneficial, since it allows sandboxing and -similar. - -(cherry picked from commit 165a476841ff1aa3aab3508771db9495ab073c7a) - -Signed-off-by: Guorui Yu ---- - src/cryptsetup/cryptsetup.c | 37 ++++++++++++++++++++++++++++++++----- - 1 file changed, 32 insertions(+), 5 deletions(-) - -diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c -index 11162eb722..9251e0eba8 100644 ---- a/src/cryptsetup/cryptsetup.c -+++ b/src/cryptsetup/cryptsetup.c -@@ -17,6 +17,7 @@ - #include "mount-util.h" - #include "parse-util.h" - #include "path-util.h" -+#include "random-util.h" - #include "string-util.h" - #include "strv.h" - #include "util.h" -@@ -480,6 +481,15 @@ static int attach_tcrypt( - return 0; - } - -+static char *make_bindname(const char *volume) { -+ char *s; -+ -+ if (asprintf(&s, "@%" PRIx64"/cryptsetup/%s", random_u64(), volume) < 0) -+ return NULL; -+ -+ return s; -+} -+ - static int attach_luks_or_plain(struct crypt_device *cd, - const char *name, - const char *key_file, -@@ -553,13 +563,30 @@ static int attach_luks_or_plain(struct crypt_device *cd, - crypt_get_device_name(cd)); - - if (key_file) { -- r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags); -- if (r == -EPERM) { -- log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); -+ _cleanup_(erase_and_freep) char *kfdata = NULL; -+ _cleanup_free_ char *bindname = NULL; -+ size_t kfsize; -+ -+ /* If we read the key via AF_UNIX, make this client recognizable */ -+ bindname = make_bindname(name); -+ if (!bindname) -+ return log_oom(); -+ -+ r = read_full_file_full( -+ AT_FDCWD, key_file, -+ arg_keyfile_offset == 0 ? UINT64_MAX : arg_keyfile_offset, -+ arg_keyfile_size == 0 ? SIZE_MAX : arg_keyfile_size, -+ READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET, -+ bindname, -+ &kfdata, &kfsize); -+ if (r == -ENOENT) { -+ log_error_errno(r, "Failed to activate, key file '%s' missing.", key_file); - return -EAGAIN; /* Log actual error, but return EAGAIN */ - } -- if (r == -EINVAL) { -- log_error_errno(r, "Failed to activate with key file '%s'. (Key file missing?)", key_file); -+ -+ r = crypt_activate_by_passphrase(cd, name, arg_key_slot, kfdata, kfsize, flags); -+ if (r == -EPERM) { -+ log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); - return -EAGAIN; /* Log actual error, but return EAGAIN */ - } - if (r < 0) --- -2.39.1 - diff --git a/10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch b/10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch deleted file mode 100644 index fbc76ac..0000000 --- a/10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch +++ /dev/null @@ -1,69 +0,0 @@ -From b877c3b06f15a025748b9f09621ddf1bd00cacce Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Fri, 20 Dec 2019 17:58:03 +0100 -Subject: [PATCH] umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed - success - -Fixes: #14410 -Replaces: #14386 - -For Lifsea-ng, this patch fixes the problem that the system occasionally -fail to shutdown caused by /sysroot unable to umount. - ---- - systemd-239/src/core/umount.c | 29 ++++++++++++++++++++++------- - 1 file changed, 22 insertions(+), 7 deletions(-) - -diff --git a/src/core/umount.c b/src/core/umount.c -index 241fe6f..4400b3c 100644 ---- a/src/core/umount.c -+++ b/src/core/umount.c -@@ -334,23 +334,38 @@ static int dm_list_get(MountPoint **head) { - - static int delete_loopback(const char *device) { - _cleanup_close_ int fd = -1; -- int r; -+ struct loop_info64 info; - - assert(device); - - fd = open(device, O_RDONLY|O_CLOEXEC); - if (fd < 0) - return errno == ENOENT ? 0 : -errno; -+ -+ if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { -+ if (errno == ENXIO) /* Nothing bound, didn't do anything */ -+ return 0; -+ -+ return -errno; -+ } - -- r = ioctl(fd, LOOP_CLR_FD, 0); -- if (r >= 0) -+ if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) { -+ /* If the LOOP_CLR_FD above succeeded we'll see ENXIO here. */ -+ if (errno == ENXIO) -+ log_debug("Successfully detached loopback device %s.", device); -+ else -+ log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device); /* the LOOP_CLR_FD at least worked, let's hope for the best */ - return 1; -+ } - -- /* ENXIO: not bound, so no error */ -- if (errno == ENXIO) -- return 0; -+ /* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing -+ * anything. Very confusing. Let's hence not claim we did anything in this case. */ -+ if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) -+ log_debug("Successfully called LOOP_CLR_FD on a loopback device %s with autoclear set, which is a NOP.", device); -+ else -+ log_debug("Weird, LOOP_CLR_FD succeeded but the device is still attached on %s.", device); - -- return -errno; -+ return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */; - } - - static int delete_dm(dev_t devnum) { --- -2.31.1 - diff --git a/20001-hwdb-parse_hwdb_dot_py.patch b/20001-hwdb-parse_hwdb_dot_py.patch deleted file mode 100644 index 71bf1c5..0000000 --- a/20001-hwdb-parse_hwdb_dot_py.patch +++ /dev/null @@ -1,299 +0,0 @@ -From: rpm-build -Date: Thu, 28 Apr 2022 01:49:39 +0000 -Subject: [PATCH] Update upstream parse_hwdb.py to fix parse-hwdb error - -This patch does not correspond to a specific commit from upstream. Instead, it -is directly taken from - -https://github.com/systemd/systemd/blob/f2c36c0e2445fa95ba109017d4b768b2fd825c43/hwdb.d/parse_hwdb.py. - -This patch allows systemd-udev to parse newer hwdb. Hwdb is updated mostly -because of new hardware. Therefore, this patch allows systemd-udev to recongnize -these new hardware. - ---- -diff -uNrp systemd-239.orig/hwdb/parse_hwdb.py systemd-239/hwdb/parse_hwdb.py ---- systemd-239.orig/hwdb/parse_hwdb.py 2022-04-28 11:32:08.740731756 +0800 -+++ systemd-239/hwdb/parse_hwdb.py 2022-04-28 11:32:08.741731786 +0800 -@@ -1,6 +1,5 @@ - #!/usr/bin/env python3 --# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ --# SPDX-License-Identifier: MIT -+# SPDX-License-Identifier: MIT - # - # This file is distributed under the MIT license, see below. - # -@@ -30,12 +29,11 @@ import sys - import os - - try: -- from pyparsing import (Word, White, Literal, ParserElement, Regex, -- LineStart, LineEnd, -+ from pyparsing import (Word, White, Literal, ParserElement, Regex, LineEnd, - OneOrMore, Combine, Or, Optional, Suppress, Group, - nums, alphanums, printables, -- stringEnd, pythonStyleComment, QuotedString, -- ParseBaseException) -+ stringEnd, pythonStyleComment, -+ ParseBaseException, __diag__) - except ImportError: - print('pyparsing is not available') - sys.exit(77) -@@ -52,33 +50,61 @@ except ImportError: - # don't do caching on old python - lru_cache = lambda: (lambda f: f) - -+__diag__.warn_multiple_tokens_in_named_alternation = True -+__diag__.warn_ungrouped_named_tokens_in_collection = True -+__diag__.warn_name_set_on_empty_Forward = True -+__diag__.warn_on_multiple_string_args_to_oneof = True -+__diag__.enable_debug_on_named_expressions = True -+ - EOL = LineEnd().suppress() - EMPTYLINE = LineEnd() - COMMENTLINE = pythonStyleComment + EOL - INTEGER = Word(nums) --STRING = QuotedString('"') - REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER)) - SIGNED_REAL = Combine(Optional(Word('-+')) + REAL) - UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_') - -+# Those patterns are used in type-specific matches - TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'), - 'evdev': ('name', 'atkbd', 'input'), -+ 'fb': ('pci'), - 'id-input': ('modalias'), - 'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'), - 'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'), - 'keyboard': ('name', ), - 'sensor': ('modalias', ), -+ 'ieee1394-unit-function' : ('node', ), -+ 'camera': ('usb'), - } - -+# Patterns that are used to set general properties on a device -+GENERAL_MATCHES = {'acpi', -+ 'bluetooth', -+ 'usb', -+ 'pci', -+ 'sdio', -+ 'vmbus', -+ 'OUI', -+ 'ieee1394', -+ } -+ -+def upperhex_word(length): -+ return Word(nums + 'ABCDEF', exact=length) -+ - @lru_cache() - def hwdb_grammar(): - ParserElement.setDefaultWhitespaceChars('') - - prefix = Or(category + ':' + Or(conn) + ':' - for category, conn in TYPES.items()) -- matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL -+ -+ matchline_typed = Combine(prefix + Word(printables + ' ' + '®')) -+ matchline_general = Combine(Or(GENERAL_MATCHES) + ':' + Word(printables + ' ' + '®')) -+ matchline = (matchline_typed | matchline_general) + EOL -+ - propertyline = (White(' ', exact=1).suppress() + -- Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) + -+ Combine(UDEV_TAG - '=' - Optional(Word(alphanums + '_=:@*.!-;, "/')) -+ - Optional(pythonStyleComment)) + - EOL) - propertycomment = White(' ', exact=1) + pythonStyleComment + EOL - -@@ -87,7 +113,7 @@ def hwdb_grammar(): - (EMPTYLINE ^ stringEnd()).suppress()) - commentgroup = OneOrMore(COMMENTLINE).suppress() - EMPTYLINE.suppress() - -- grammar = OneOrMore(group('GROUPS*') ^ commentgroup) + stringEnd() -+ grammar = OneOrMore(Group(group)('GROUPS*') ^ commentgroup) + stringEnd() - - return grammar - -@@ -95,39 +121,57 @@ def hwdb_grammar(): - def property_grammar(): - ParserElement.setDefaultWhitespaceChars(' ') - -- dpi_setting = (Optional('*')('DEFAULT') + INTEGER('DPI') + Suppress('@') + INTEGER('HZ'))('SETTINGS*') -+ dpi_setting = Group(Optional('*')('DEFAULT') + INTEGER('DPI') + Optional(Suppress('@') + INTEGER('HZ')))('SETTINGS*') - mount_matrix_row = SIGNED_REAL + ',' + SIGNED_REAL + ',' + SIGNED_REAL -- mount_matrix = (mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX') -+ mount_matrix = Group(mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX') -+ xkb_setting = Optional(Word(alphanums + '+-/@._')) -+ -+ # Although this set doesn't cover all of characters in database entries, it's enough for test targets. -+ name_literal = Word(printables + ' ') - - props = (('MOUSE_DPI', Group(OneOrMore(dpi_setting))), - ('MOUSE_WHEEL_CLICK_ANGLE', INTEGER), - ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER), - ('MOUSE_WHEEL_CLICK_COUNT', INTEGER), - ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER), -- ('ID_INPUT', Literal('1')), -- ('ID_INPUT_ACCELEROMETER', Literal('1')), -- ('ID_INPUT_JOYSTICK', Literal('1')), -- ('ID_INPUT_KEY', Literal('1')), -- ('ID_INPUT_KEYBOARD', Literal('1')), -- ('ID_INPUT_MOUSE', Literal('1')), -- ('ID_INPUT_POINTINGSTICK', Literal('1')), -- ('ID_INPUT_SWITCH', Literal('1')), -- ('ID_INPUT_TABLET', Literal('1')), -- ('ID_INPUT_TABLET_PAD', Literal('1')), -- ('ID_INPUT_TOUCHPAD', Literal('1')), -- ('ID_INPUT_TOUCHSCREEN', Literal('1')), -- ('ID_INPUT_TRACKBALL', Literal('1')), -- ('MOUSE_WHEEL_TILT_HORIZONTAL', Literal('1')), -- ('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')), -+ ('ID_AUTOSUSPEND', Or((Literal('0'), Literal('1')))), -+ ('ID_AV_PRODUCTION_CONTROLLER', Or((Literal('0'), Literal('1')))), -+ ('ID_PERSIST', Or((Literal('0'), Literal('1')))), -+ ('ID_PDA', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_ACCELEROMETER', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_JOYSTICK', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_KEY', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_KEYBOARD', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_MOUSE', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_POINTINGSTICK', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_SWITCH', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_TABLET', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_TABLET_PAD', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_TOUCHPAD', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_TOUCHSCREEN', Or((Literal('0'), Literal('1')))), -+ ('ID_INPUT_TRACKBALL', Or((Literal('0'), Literal('1')))), -+ ('ID_SIGNAL_ANALYZER', Or((Literal('0'), Literal('1')))), - ('POINTINGSTICK_SENSITIVITY', INTEGER), - ('POINTINGSTICK_CONST_ACCEL', REAL), - ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))), - ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), -- ('XKB_FIXED_LAYOUT', STRING), -- ('XKB_FIXED_VARIANT', STRING), -+ ('XKB_FIXED_LAYOUT', xkb_setting), -+ ('XKB_FIXED_VARIANT', xkb_setting), -+ ('XKB_FIXED_MODEL', xkb_setting), - ('KEYBOARD_LED_NUMLOCK', Literal('0')), - ('KEYBOARD_LED_CAPSLOCK', Literal('0')), - ('ACCEL_MOUNT_MATRIX', mount_matrix), -+ ('ACCEL_LOCATION', Or(('display', 'base'))), -+ ('PROXIMITY_NEAR_LEVEL', INTEGER), -+ ('IEEE1394_UNIT_FUNCTION_MIDI', Or((Literal('0'), Literal('1')))), -+ ('IEEE1394_UNIT_FUNCTION_AUDIO', Or((Literal('0'), Literal('1')))), -+ ('IEEE1394_UNIT_FUNCTION_VIDEO', Or((Literal('0'), Literal('1')))), -+ ('ID_VENDOR_FROM_DATABASE', name_literal), -+ ('ID_MODEL_FROM_DATABASE', name_literal), -+ ('ID_TAG_MASTER_OF_SEAT', Literal('1')), -+ ('ID_INFRARED_CAMERA', Or((Literal('0'), Literal('1')))), -+ ('ID_CAMERA_DIRECTION', Or(('front', 'rear'))), - ) - fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') - for name, val in props] -@@ -165,8 +209,29 @@ def parse(fname): - return [] - return [convert_properties(g) for g in parsed.GROUPS] - --def check_match_uniqueness(groups): -+def check_matches(groups): - matches = sum((group[0] for group in groups), []) -+ -+ # This is a partial check. The other cases could be also done, but those -+ # two are most commonly wrong. -+ grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', -+ 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', -+ } -+ -+ for match in matches: -+ prefix, rest = match.split(':', maxsplit=1) -+ gr = grammars.get(prefix) -+ if gr: -+ # we check this first to provide an easy error message -+ if rest[-1] not in '*:': -+ error('pattern {} does not end with "*" or ":"', match) -+ -+ try: -+ gr.parseString(rest) -+ except ParseBaseException as e: -+ error('Pattern {!r} is invalid: {}', rest, e) -+ continue -+ - matches.sort() - prev = None - for match in matches: -@@ -196,15 +261,25 @@ def check_one_mount_matrix(prop, value): - def check_one_keycode(prop, value): - if value != '!' and ecodes is not None: - key = 'KEY_' + value.upper() -- if key not in ecodes: -- key = value.upper() -- if key not in ecodes: -- error('Keycode {} unknown', key) -+ if not (key in ecodes or -+ value.upper() in ecodes or -+ # new keys added in kernel 5.5 -+ 'KBD_LCD_MENU' in key): -+ error('Keycode {} unknown', key) -+ -+def check_wheel_clicks(properties): -+ pairs = (('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', 'MOUSE_WHEEL_CLICK_COUNT'), -+ ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', 'MOUSE_WHEEL_CLICK_ANGLE'), -+ ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', 'MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL'), -+ ('MOUSE_WHEEL_CLICK_COUNT', 'MOUSE_WHEEL_CLICK_ANGLE')) -+ for pair in pairs: -+ if pair[0] in properties and pair[1] not in properties: -+ error('{} requires {} to be specified', *pair) - - def check_properties(groups): - grammar = property_grammar() - for matches, props in groups: -- prop_names = set() -+ seen_props = {} - for prop in props: - # print('--', prop) - prop = prop.partition('#')[0].rstrip() -@@ -214,30 +289,35 @@ def check_properties(groups): - error('Failed to parse: {!r}', prop) - continue - # print('{!r}'.format(parsed)) -- if parsed.NAME in prop_names: -+ if parsed.NAME in seen_props: - error('Property {} is duplicated', parsed.NAME) -- prop_names.add(parsed.NAME) -+ seen_props[parsed.NAME] = parsed.VALUE - if parsed.NAME == 'MOUSE_DPI': - check_one_default(prop, parsed.VALUE.SETTINGS) - elif parsed.NAME == 'ACCEL_MOUNT_MATRIX': - check_one_mount_matrix(prop, parsed.VALUE) - elif parsed.NAME.startswith('KEYBOARD_KEY_'): -- check_one_keycode(prop, parsed.VALUE) -+ val = parsed.VALUE if isinstance(parsed.VALUE, str) else parsed.VALUE[0] -+ check_one_keycode(prop, val) -+ -+ check_wheel_clicks(seen_props) - - def print_summary(fname, groups): -+ n_matches = sum(len(matches) for matches, props in groups) -+ n_props = sum(len(props) for matches, props in groups) - print('{}: {} match groups, {} matches, {} properties' -- .format(fname, -- len(groups), -- sum(len(matches) for matches, props in groups), -- sum(len(props) for matches, props in groups))) -+ .format(fname, len(groups), n_matches, n_props)) -+ -+ if n_matches == 0 or n_props == 0: -+ error('{}: no matches or props'.format(fname)) - - if __name__ == '__main__': -- args = sys.argv[1:] or glob.glob(os.path.dirname(sys.argv[0]) + '/[67]0-*.hwdb') -+ args = sys.argv[1:] or sorted(glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb')) - - for fname in args: - groups = parse(fname) - print_summary(fname, groups) -- check_match_uniqueness(groups) -+ check_matches(groups) - check_properties(groups) - - sys.exit(ERROR) diff --git a/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch b/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch deleted file mode 100644 index 7d81489..0000000 --- a/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 62f8dac80e5f908f83b6e7cd06629055184c25d7 Mon Sep 17 00:00:00 2001 -From: Forrestly -Date: Thu, 23 Mar 2023 10:08:33 +0800 -Subject: [PATCH] cgroup: do not refresh cgroup devices config when - daemon-reload(#42937798) - -Signed-off-by: Forrestly ---- - src/core/cgroup.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index 50d2738..ea92aa6 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -1920,6 +1920,7 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) { - enable_mask = unit_get_enable_mask(u); - needs_bpf = unit_get_needs_bpf(u); - -+ target_mask &= ~CGROUP_MASK_DEVICES; - if (unit_has_mask_realized(u, target_mask, enable_mask, needs_bpf)) - return 0; - --- -2.34.1 - diff --git a/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch b/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch deleted file mode 100644 index 21c5557..0000000 --- a/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch +++ /dev/null @@ -1,133 +0,0 @@ -From f25124fabe1ed973840291d46549af6e1c5fad56 Mon Sep 17 00:00:00 2001 -From: "zhongling.h" -Date: Fri, 4 Aug 2023 10:08:16 +0800 -Subject: [PATCH] core: introduce cgroup full delegation for compability - -While using systemd-219, users can set 'delegate=y' to claim the -possession of cgroup settings. By then, users are able to write raw -values under /sys/fs/cgroup to adjust cgroup settings and systemd -won't touch these values any longer. - -However, this is likely to be an undefined behaviour for systemd-219. -Upon releasing systemd-239, a documentation of cgroup delegation was -added, -https://github.com/systemd/systemd/commit/e30eaff3a32523b09d61af67fc999f1f62f4e0cb. -It states that: - -Only sub-trees can be delegated (though whoever decides to request a -sub-tree can delegate sub-sub-trees further to somebody else if they -like it).' - -Which is quite different from what people understand the delegation of -systemd-219. Currently, whether a unit is delegated or not, systemd always -possesses any cgroup it created, only ignoring the sub-tree ones -according to delegation settings. - -This behaviour change causes confusion if users switch from systemd-219 to -systemd-239. As a result, we introduce 'FullDelegation', a feature that -brings what users are already familiar with to systemd-239. If users set -'FullDelegation=yes' in /etc/systemd/system.conf, they can control raw -values under /sys/fs/cgroup without worrying systemd touching these -values, which is the same as what they expected with systemd-219. - ---- - src/core/cgroup.c | 16 ++++++++++++++++ - src/core/main.c | 4 ++++ - src/core/manager.h | 1 + - src/core/system.conf.in | 1 + - 4 files changed, 22 insertions(+) - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index ea92aa6f7b..17e3b90e37 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -1692,6 +1692,15 @@ static int unit_create_cgroup( - /* Keep track that this is now realized */ - u->cgroup_realized = true; - u->cgroup_realized_mask = target_mask; -+ -+ // While realizing cgroup, we don't realize delegated cgroup, therefore, target_mask -+ // doesn't contain delegated cgroup controller bit, and u->cgroup_realized_mask will -+ // not contain delegated cgroup controller bit as well. This unit will be in a state -+ // as if delegated cgroup is not set, which is not expected. -+ // If this is not present, delegated cgroup will be set every 2 systemctl daemon-reload -+ if (u->manager->full_delegation && unit_cgroup_delegate(u)) -+ u->cgroup_realized_mask |= unit_get_delegate_mask(u); -+ - u->cgroup_enabled_mask = enable_mask; - u->cgroup_bpf_state = needs_bpf ? UNIT_CGROUP_BPF_ON : UNIT_CGROUP_BPF_OFF; - -@@ -1921,6 +1930,10 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) { - needs_bpf = unit_get_needs_bpf(u); - - target_mask &= ~CGROUP_MASK_DEVICES; -+ -+ if (u->manager->full_delegation && unit_cgroup_delegate(u)) -+ target_mask ^= u->cgroup_realized_mask; -+ - if (unit_has_mask_realized(u, target_mask, enable_mask, needs_bpf)) - return 0; - -@@ -2883,6 +2896,9 @@ int unit_reset_ip_accounting(Unit *u) { - void unit_invalidate_cgroup(Unit *u, CGroupMask m) { - assert(u); - -+ if (u->manager->full_delegation) -+ m ^= unit_get_delegate_mask(u); // don't invalidate delegated cgroup -+ - if (!UNIT_HAS_CGROUP_CONTEXT(u)) - return; - -diff --git a/src/core/main.c b/src/core/main.c -index 546bf0d870..68daf07077 100644 ---- a/src/core/main.c -+++ b/src/core/main.c -@@ -142,6 +142,7 @@ static bool reexec_jmp_can = false; - static bool reexec_jmp_inited = false; - static sigjmp_buf reexec_jmp_buf; - static bool arg_default_cpuset_clone_children = false; -+static bool arg_full_delegation = false; - - static int parse_configuration(const struct rlimit *saved_rlimit_nofile, - const struct rlimit *saved_rlimit_memlock); -@@ -768,6 +769,8 @@ static int parse_config_file(void) { - { "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max }, - { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action }, - { "Manager", "DefaultCPUSetCloneChildren",config_parse_bool, 0, &arg_default_cpuset_clone_children }, -+ { "Manager", "FullDelegation", config_parse_bool, 0, &arg_full_delegation }, -+ - {} - }; - -@@ -817,6 +820,7 @@ static void set_manager_defaults(Manager *m) { - m->default_memory_accounting = arg_default_memory_accounting; - m->default_tasks_accounting = arg_default_tasks_accounting; - m->default_tasks_max = arg_default_tasks_max; -+ m->full_delegation = arg_full_delegation; - - manager_set_default_rlimits(m, arg_default_rlimit); - manager_environment_add(m, NULL, arg_default_environment); -diff --git a/src/core/manager.h b/src/core/manager.h -index 98d381bc5b..91f2c05afe 100644 ---- a/src/core/manager.h -+++ b/src/core/manager.h -@@ -297,6 +297,7 @@ struct Manager { - bool default_blockio_accounting; - bool default_tasks_accounting; - bool default_ip_accounting; -+ bool full_delegation; - - uint64_t default_tasks_max; - usec_t default_timer_accuracy_usec; -diff --git a/src/core/system.conf.in b/src/core/system.conf.in -index 2f6852a89f..6c84a55401 100644 ---- a/src/core/system.conf.in -+++ b/src/core/system.conf.in -@@ -67,3 +67,4 @@ DefaultLimitCORE=0:infinity - #DefaultLimitRTTIME= - #IPAddressAllow= - #IPAddressDeny= -+#FullDelegation=no --- -2.39.3 - diff --git a/README.md b/README.md deleted file mode 100644 index 7d30ca3..0000000 --- a/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# systemd-239 - -This is the repository of systemd-239 for Anolis OS 8. - -## Patch index convention - -Below is the patch index convention of this repository: - -- 0001 ... 0xxx : patches from upstream srpm -- 10001 ... 10xxx : patches cherry-picked from systemd github upstream -- 20001 ... 20xxx : original patch by OpenAnolis community \ No newline at end of file diff --git a/dist b/dist index 5aa45c5..9c0e36e 100644 --- a/dist +++ b/dist @@ -1 +1 @@ -an8_8 +an8 diff --git a/systemd.spec b/systemd.spec index 7bbb232..25e87ae 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1,4 +1,3 @@ -%define anolis_release .0.3 #global gitcommit 10e465b5321bd53c1fc59ffab27e724535c6bc0f %{?gitcommit:%global gitcommitshort %(c=%{gitcommit}; echo ${c:0:7})} @@ -14,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 74%{anolis_release}%{?dist}.3 +Release: 78%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -955,47 +954,81 @@ Patch0901: 0901-man-document-the-new-_LINE_BREAK-type.patch Patch0902: 0902-journald-server-always-create-state-file-in-signal-h.patch Patch0903: 0903-journald-server-move-relinquish-code-into-function.patch Patch0904: 0904-journald-server-always-touch-state-file-in-signal-ha.patch -Patch0905: 0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch -Patch0906: 0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch -Patch0907: 0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch -Patch0908: 0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch -Patch0909: 0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch -Patch0910: 0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch -Patch0911: 0911-ci-first-part-of-the-source-git-automation-commit-li.patch -Patch0912: 0912-login-add-a-missing-error-check-for-session_set_lead.patch -Patch0913: 0913-logind-reset-session-leader-if-we-know-for-a-fact-th.patch - -Patch10000: 10000-core-fix-a-null-reference-case-in-load_from_path.patch -Patch10001: 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch -Patch10002: 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch -Patch10003: 10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch -Patch10004: 10004-Do-not-go-into-freeze-when-systemd-crashd.patch -Patch10005: 10005-mount-setup-change-the-system-mount-propagation-to-s.patch -Patch10006: 10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch -Patch10007: 10007-cgroup-update-only-siblings-that-got-realized-once.patch -Patch10008: 10008-core-add-a-config-item-to-support-setting-the-value-.patch -Patch10009: 10009-systemd-anolis-support-loongarch64.patch -Patch10010: 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch -Patch10011: 10011-hwdb-add-Iluvatar-CoreX.patch -Patch10012: 10012-seccomp-add-loongarch-support.patch -Patch10013: 10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch -Patch10014: 10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch -Patch10015: 10015-util-introduce-erase_and_free-helper.patch -Patch10016: 10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch -Patch10017: 10017-fileio-introduce-warn_file_is_world_accessible.patch -Patch10018: 10018-fileio-read_full_file_full-also-warns-when-file-is-.patch -Patch10019: 10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch -Patch10020: 10020-fileio-add-explicit-flag-for-generating-world-execu.patch -Patch10021: 10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch -Patch10022: 10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch -Patch10023: 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch -Patch10024: 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch -Patch10025: 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch -Patch10026: 10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch - -Patch20001: 20001-hwdb-parse_hwdb_dot_py.patch -Patch20002: 20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch -Patch20003: 20003-core-introduce-cgroup-full-delegation-for-compabilit.patch +Patch0905: 0905-test-make-TEST-35-LOGIN-stable-again.patch +Patch0906: 0906-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch +Patch0907: 0907-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch +Patch0908: 0908-pager-make-pager-secure-when-under-euid-is-changed-o.patch +Patch0909: 0909-ci-trigger-differential-shellcheck-workflow-on-push.patch +Patch0910: 0910-ci-codeql-master-main.patch +Patch0911: 0911-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch +Patch0912: 0912-ci-Mergify-drop-requirements-on-linting-workflows.patch +Patch0913: 0913-ci-workflow-for-gathering-metadata-for-source-git-au.patch +Patch0914: 0914-ci-first-part-of-the-source-git-automation-commit-li.patch +Patch0915: 0915-pstore-fix-crash-and-forward-dummy-arguments-instead.patch +Patch0916: 0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch +Patch0917: 0917-pstore-explicitly-set-the-base-when-converting-recor.patch +Patch0918: 0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch +Patch0919: 0919-test-add-a-couple-of-tests-for-systemd-pstore.patch +Patch0920: 0920-ci-update-permissions-for-source-git-automation-work.patch +Patch0921: 0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch +Patch0922: 0922-parse-util-in-parse_permille-check-negative-earlier.patch +Patch0923: 0923-tree-wide-increase-granularity-of-percent-specificat.patch +Patch0924: 0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch +Patch0925: 0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch +Patch0926: 0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch +Patch0927: 0927-sd-bus-handle-EINTR-return-from-bus_poll.patch +Patch0928: 0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch +Patch0929: 0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch +Patch0930: 0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch +Patch0931: 0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch +Patch0932: 0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch +Patch0933: 0933-journal-vacuum-count-size-of-all-journal-files.patch +Patch0934: 0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch +Patch0935: 0935-resolved-close-UDP-socket-when-we-received-a-network.patch +Patch0936: 0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch +Patch0937: 0937-man-tweak-markup-in-systemd-pstore.service-8.patch +Patch0938: 0938-man-add-.service-suffix-to-systemd-pstore-8.patch +Patch0939: 0939-presets-enable-systemd-pstore.service-by-default.patch +Patch0940: 0940-logind-simplify-code.patch +Patch0941: 0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch +Patch0942: 0942-loginctl-shorten-variable-name.patch +Patch0943: 0943-loginctl-use-bus_map_all_properties.patch +Patch0944: 0944-loginctl-show-session-idle-status-in-list-sessions.patch +Patch0945: 0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch +Patch0946: 0946-loginctl-also-show-idle-hint-in-session-status.patch +Patch0947: 0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch +Patch0948: 0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch +Patch0949: 0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch +Patch0950: 0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch +Patch0951: 0951-login-add-a-missing-error-check-for-session_set_lead.patch +Patch0952: 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch +Patch0953: 0953-test-login-skip-consistency-checks-when-logind-is-no.patch +Patch0954: 0954-sd-event-remove-dead-code-and-use-_cleanup_.patch +Patch0955: 0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch +Patch0956: 0956-sd-event-add-sd_event_add_inotify_fd-call.patch +Patch0957: 0957-test-add-test-case-for-self-destroy-inotify-handler.patch +Patch0958: 0958-doc-add-downstream-CONTRIBUTING-document.patch +Patch0959: 0959-doc-use-link-with-prefilled-Jira-issue.patch +Patch0960: 0960-docs-link-downstream-CONTRIBUTING-in-README.patch +Patch0961: 0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch +Patch0962: 0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch +Patch0963: 0963-test-set-indentation-to-4-spaces.patch +Patch0964: 0964-test-TEST-15-remove-all-created-unit-files.patch +Patch0965: 0965-test-use-quotes-where-necessary.patch +Patch0966: 0966-tree-wide-drop-manually-crafted-message-for-missing-.patch +Patch0967: 0967-manager-reformat-boolean-expression-in-unit_is_prist.patch +Patch0968: 0968-manager-allow-transient-units-to-have-drop-ins.patch +Patch0969: 0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch +Patch0970: 0970-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch +Patch0971: 0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch +Patch0972: 0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch +Patch0973: 0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch +Patch0974: 0974-meson-remove-libdw-dependency-from-pstore.patch +Patch0975: 0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch +Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch +Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch +Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch +Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1493,32 +1526,32 @@ fi %{?ldconfig} function mod_nss() { - if [ -f "$1" ] ; then - # sed-fu to add myhostname to hosts line - grep -E -q '^hosts:.* myhostname' "$1" || + if [ $1 -eq 1 ] && [ -f "$2" ]; then + # sed-fu to add myhostname to hosts line (only once, on install) + grep -E -q '^hosts:.* myhostname' "$2" || sed -i.bak -e ' /^hosts:/ !b /\/ b s/[[:blank:]]*$/ myhostname/ - ' "$1" &>/dev/null || : + ' "$2" &>/dev/null || : - # Add nss-systemd to passwd and group - grep -E -q '^(passwd|group):.* systemd' "$1" || + # Add nss-systemd to passwd and group (only once, on install) + grep -E -q '^(passwd|group):.* systemd' "$2" || sed -i.bak -r -e ' s/^(passwd|group):(.*)/\1: \2 systemd/ - ' "$1" &>/dev/null || : + ' "$2" &>/dev/null || : fi } FILE="$(readlink /etc/nsswitch.conf || echo /etc/nsswitch.conf)" if [ "$FILE" = "/etc/authselect/nsswitch.conf" ] && authselect check &>/dev/null; then - mod_nss "/etc/authselect/user-nsswitch.conf" + mod_nss $1 "/etc/authselect/user-nsswitch.conf" authselect apply-changes &> /dev/null || : else - mod_nss "$FILE" + mod_nss $1 "$FILE" # also apply the same changes to user-nsswitch.conf to affect # possible future authselect configuration - mod_nss "/etc/authselect/user-nsswitch.conf" + mod_nss $1 "/etc/authselect/user-nsswitch.conf" fi # check if nobody or nfsnobody is defined @@ -1626,55 +1659,91 @@ fi %files tests -f .file-list-tests %changelog -* Mon Oct 30 2023 Zhongling He - 239.74.0.3.3 -- Update upstream parse_hwdb.py to fix parse-hwdb error -- cgroup: do not refresh cgroup devices config when daemon-reload -- core: introduce cgroup full delegation for compability - -* Wed Sep 06 2023 Yuanhong Peng - 239-74.0.2.3 -- core: fix a null reference case in load_from_path() -- sysctl: Don't pass null directive argument to '%s' -- exit-status: introduce EXIT_EXCEPTION mapping to 255 -- main: don't freeze PID 1 in containers, exit with non-zero instead -- Do not go into freeze when systemd crashd -- mount-setup: change the system mount propagation to shared by default only at bootup -- cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() unsigned -- cgroup: update only siblings that got realized once -- core: add a config item to support setting the value of cpuset.clone_children when systemd is starting -- support loongarch for systemd -- test-catalog: Fix coredump when compiled under GCC10 -- add Iluvatar CoreX pci id (Liwei Ge) -- seccomp: add loongarch64 support (Liwei Ge) -- seccomp: remove loongarch64 switch(Liwei Ge) -- umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed success(yuanhui) -- fileio: when reading a full file into memory, refuse inner NUL bytes (Guorui Yu) -- util: introduce explicit_bzero_safe for explicit memset (Guorui Yu) -- util: introduce erase_and_free() helper (Guorui Yu) -- util: introduce READ_FULL_FILE_SECURE flag for reading secure data (Guorui Yu) -- fileio: introduce warn_file_is_world_accessible() (Guorui Yu) -- fileio: read_full_file_full() also warns when file is world readable and secure flag is set (Guorui Yu) -- basic/fileio: Fix memory leak if READ_FULL_FILE_SECURE flag is used (Guorui Yu) -- fileio: add explicit flag for generating world executable warning when reading file (Guorui Yu) -- fileio: add 'dir_fd' parameter to read_full_file_full() (Guorui Yu) -- fileio: add support for read_full_file() on AF_UNIX stream sockets (Guorui Yu) -- fileio: beef up READ_FULL_FILE_CONNECT_SOCKET to allow setting sender socket name (Guorui Yu) -- fileio: teach read_full_file_full() to read from offset/with maximum size (Guorui Yu) -- cryptsetup: port cryptsetup's main key file logic over to read_full_file_full() (Guorui Yu) - -* Thu Jul 20 2023 systemd maintenance team - 239-74.3 -- login: add a missing error check for session_set_leader() (#2223602) -- logind: reset session leader if we know for a fact that it is gone (#2223602) - -* Thu May 18 2023 systemd maintenance team - 239-74.2 -- pstore: fix crash and forward dummy arguments instead of NULL (#2190153) -- ci: workflow for gathering metadata for source-git automation (#2190153) -- ci: first part of the source-git automation - commit linter (#2190153) - -* Tue Apr 18 2023 systemd maintenance team - 239-74.1 -- pager: set $LESSSECURE whenver we invoke a pager (#2175623) -- test-login: always test sd_pid_get_owner_uid(), modernize (#2175623) -- pager: make pager secure when under euid is changed or explicitly requested (#2175623) -- test: ignore ENOMEDIUM error from sd_pid_get_cgroup() (#2175623) +* Tue Aug 22 2023 systemd maintenance team - 239-78 +- login: add a missing error check for session_set_leader() (#2158167) +- logind: reset session leader if we know for a fact that it is gone (#2158167) +- test-login: skip consistency checks when logind is not active (#2223582) +- sd-event: remove dead code and use _cleanup_ (#2211358) +- sd-event: don't destroy inotify data structures from inotify event handler (#2211358) +- sd-event: add sd_event_add_inotify_fd() call (#2211358) +- test: add test case for self-destroy inotify handler (#2211358) +- doc: add downstream CONTRIBUTING document (#2179309) +- doc: use link with prefilled Jira issue (#2179309) +- docs: link downstream CONTRIBUTING in README (#2179309) +- unit drop-in: Fix ordering of special type.d drop-ins (#2156620) +- Add failing test to show service.d global drop-in does not get overridden by more specific dropins (#2156620) +- test: set indentation to 4 spaces (#2156620) +- test/TEST-15: remove all created unit files (#2156620) +- test: use quotes where necessary (#2156620) +- tree-wide: drop manually-crafted message for missing variables (#2156620) +- manager: reformat boolean expression in unit_is_pristine() (#2156620) +- manager: allow transient units to have drop-ins (#2156620) +- TEST-15: allow helper functions to accept other unit types (#2156620) +- TEST-15: also test hierarchical drop-ins for slices (#2156620) +- TEST-15: add test for transient units with drop-ins (#2156620) +- TEST-15: add one more test for drop-in precedence (#2156620) +- udev/net_id: introduce naming scheme for RHEL-8.9 (#2231846) +- meson: remove libdw dependency from pstore (#2211416) +- pstore: introduce tmpfiles.d/systemd-pstore.conf (#2211416) +- tmpfiles: don't complain if we can't enable pstore in containers (#2211416) +- pstore: don't enable crash_kexec_post_notifiers by default (#2211416) +- core: when Delegate=yes is set for a unit, run ExecStartPre= and friends in a subcgroup of the unit (#2215925) +- man: link Delegate= documentation up with the markdown docs (#2215925) + +* Mon Jul 17 2023 systemd maintenance team - 239-77 +- ci: update permissions for source-git automation workflows (#2179309) +- sulogin: fix control lost of the current terminal when default.target is rescue.target (#2169932) +- parse-util: in parse_permille() check negative earlier (#2178179) +- tree-wide: increase granularity of percent specifications all over the place to permille (#2178179) +- errno-util: introduce ERRNO_IS_TRANSIENT() (#2172846) +- tree-wide: use ERRNO_IS_TRANSIENT() (#2172846) +- libsystemd: ignore both EINTR and EAGAIN (#2172846) +- sd-bus: handle -EINTR return from bus_poll() (#2172846) +- stdio-bridge: don't be bothered with EINTR (#2172846) +- sd-netlink: handle EINTR from poll() gracefully, as success (#2172846) +- resolved: handle -EINTR returned from fd_wait_for_event() better (#2172846) +- utmp-wtmp: fix error in case isatty() fails (#2172846) +- utmp-wtmp: handle EINTR gracefully when waiting to write to tty (#2172846) +- journal-vacuum: count size of all journal files (#2180380) +- resolved: instead of closing DNS UDP transaction fds right-away, add them to a socket "graveyard" (#2156751) +- resolved: close UDP socket when we received a network error on it (#2156751) +- ci: allow RHEL-only labels to mark downstream-only commits (#2179309) +- man: tweak markup in systemd-pstore.service(8) (#2217786) +- man: add .service suffix to systemd-pstore(8) (#2217786) +- presets: enable systemd-pstore.service by default (#2217786) +- logind: simplify code (#2209328) +- format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE (#2156786) +- loginctl: shorten variable name (#2156786) +- loginctl: use bus_map_all_properties (#2156786) +- loginctl: show session idle status in list-sessions (#2156786) +- loginctl: list-sessions: fix timestamp for idle hint (#2156786) +- loginctl: also show idle hint in session-status (#2156786) +- core/timer: Always use inactive_exit_timestamp if it is set (#1719364) +- timer: Use dual_timestamp_is_set() in one more place (#1719364) +- ci: drop systemd-stable from advanced-commit-linter config (#2179309) +- core/mount: escape invalid UTF8 char in dbus reply (#2158724) + +* Thu May 18 2023 systemd maintenance team - 239-76 +- ci(Mergify): drop requirements on linting workflows (#2179309) +- ci: workflow for gathering metadata for source-git automation (#2179309) +- ci: first part of the source-git automation - commit linter (#2179309) +- pstore: fix crash and forward dummy arguments instead of NULL (#2190151) +- test: Disable LUKS devices from initramfs in QEMU tests (#2190151) +- pstore: explicitly set the base when converting record ID (#2190151) +- pstore: avoid opening the dmesg.txt file if not requested (#2190151) +- test: add a couple of tests for systemd-pstore (#2190151) + +* Tue Apr 18 2023 systemd maintenance team - 239-75 +- journald-server: always create state file in signal handler (#2176892) +- journald-server: move relinquish code into function (#2176892) +- journald-server: always touch state file in signal handler (#2176892) +- test: make TEST-35-LOGIN stable again (#2179309) +- pager: set $LESSSECURE whenver we invoke a pager (#2175624) +- test-login: always test sd_pid_get_owner_uid(), modernize (#2175624) +- pager: make pager secure when under euid is changed or explicitly requested (#2175624) +- ci: trigger differential-shellcheck workflow on push (#2179309) +- ci: codeql `master` -> `main` (#2179309) +- test: ignore ENOMEDIUM error from sd_pid_get_cgroup() (#2175622) * Tue Mar 14 2023 systemd maintenance team - 239-74 - journald-server: always create state file in signal handler (#2174645) -- Gitee From d1a62c18c01be466ab38cf0233ade319e1a27eb2 Mon Sep 17 00:00:00 2001 From: pangqing Date: Tue, 19 Apr 2022 15:08:32 +0800 Subject: [PATCH 02/11] Add optimized patches Signed-off-by: Yuanhong Peng --- ...ull-reference-case-in-load_from_path.patch | 34 +++++ ...-t-pass-null-directive-argument-to-s.patch | 25 ++++ ...roduce-EXIT_EXCEPTION-mapping-to-255.patch | 52 ++++++++ ...e-PID-1-in-containers-exit-with-non-.patch | 52 ++++++++ ...t-go-into-freeze-when-systemd-crashd.patch | 103 +++++++++++++++ ...ge-the-system-mount-propagation-to-s.patch | 62 +++++++++ ...-definition-of-CGROUP_CONTROLLER_TO_.patch | 26 ++++ ...only-siblings-that-got-realized-once.patch | 46 +++++++ ...g-item-to-support-setting-the-value-.patch | 120 ++++++++++++++++++ ...9-systemd-anolis-support-loongarch64.patch | 56 ++++++++ systemd.spec | 25 +++- 11 files changed, 600 insertions(+), 1 deletion(-) create mode 100644 10000-core-fix-a-null-reference-case-in-load_from_path.patch create mode 100644 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch create mode 100644 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch create mode 100644 10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch create mode 100644 10004-Do-not-go-into-freeze-when-systemd-crashd.patch create mode 100644 10005-mount-setup-change-the-system-mount-propagation-to-s.patch create mode 100644 10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch create mode 100644 10007-cgroup-update-only-siblings-that-got-realized-once.patch create mode 100644 10008-core-add-a-config-item-to-support-setting-the-value-.patch create mode 100644 10009-systemd-anolis-support-loongarch64.patch diff --git a/10000-core-fix-a-null-reference-case-in-load_from_path.patch b/10000-core-fix-a-null-reference-case-in-load_from_path.patch new file mode 100644 index 0000000..e15690c --- /dev/null +++ b/10000-core-fix-a-null-reference-case-in-load_from_path.patch @@ -0,0 +1,34 @@ +From 11e4aae398f9d26c7c4e54bfa6621f80a3ed2100 Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Tue, 19 Apr 2022 11:04:47 +0800 +Subject: [PATCH] fix a null reference case in load_from_path() + +--- + src/core/load-fragment.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index c0b1fd4..f59a040 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -4477,7 +4477,6 @@ static int load_from_path(Unit *u, const char *path) { + r = open_follow(&filename, &f, symlink_names, &id); + if (r >= 0) + break; +- filename = mfree(filename); + + /* ENOENT means that the file is missing or is a dangling symlink. + * ENOTDIR means that one of paths we expect to be is a directory +@@ -4486,7 +4485,8 @@ static int load_from_path(Unit *u, const char *path) { + */ + if (r == -EACCES) + log_debug_errno(r, "Cannot access \"%s\": %m", filename); +- else if (!IN_SET(r, -ENOENT, -ENOTDIR)) ++ filename = mfree(filename); ++ if (!IN_SET(r, -ENOENT, -ENOTDIR)) + return r; + + /* Empty the symlink names for the next run */ +-- +2.27.0 + diff --git a/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch b/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch new file mode 100644 index 0000000..ec09ee4 --- /dev/null +++ b/10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch @@ -0,0 +1,25 @@ +From 1b3f7805ed7c193e17cb5bad4f4f19c2f72f3d08 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Tue, 19 Apr 2022 11:16:42 +0800 +Subject: [PATCH] sysctl: Don't pass null directive argument to '%s' + +--- + src/sysctl/sysctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 4c85d68..e756eff 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -160,7 +160,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + value = strchr(p, '='); + if (!value) { +- log_error("Line is not an assignment at '%s:%u': %s", path, c, value); ++ log_error("Line is not an assignment at '%s:%u': %s", path, c, p); + + if (r == 0) + r = -EINVAL; +-- +2.27.0 + diff --git a/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch b/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch new file mode 100644 index 0000000..66539a0 --- /dev/null +++ b/10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch @@ -0,0 +1,52 @@ +From f7940c9cdf872d7504aca9637e9fd14328b2b726 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 19 Apr 2022 11:26:10 +0800 +Subject: [PATCH] exit-status: introduce EXIT_EXCEPTION mapping to 255 + +--- + src/basic/exit-status.c | 9 ++++++--- + src/basic/exit-status.h | 1 + + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c +index 0a7a53b..8b67d44 100644 +--- a/src/basic/exit-status.c ++++ b/src/basic/exit-status.c +@@ -19,9 +19,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { + * 79…199 │ (Currently unmapped) + * 200…241 │ systemd's private error codes (might be extended to 254 in future development) + * 242…254 │ (Currently unmapped, but see above) +- * 255 │ (We should probably stay away from that one, it's frequently used by applications to indicate an +- * │ exit reason that cannot really be expressed in a single exit status value — such as a propagated +- * │ signal or such) ++ * 255 │ EXIT_EXCEPTION (We use this to propagate exit-by-signal events. It's frequently used by others apps (like bash) ++ * │ to indicate exit reason that cannot really be expressed in a single exit status value — such as a propagated ++ * │ signal or such, and we follow that logic here.) + */ + + switch (status) { /* We always cover the ISO C ones */ +@@ -158,6 +158,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { + + case EXIT_NUMA_POLICY: + return "NUMA_POLICY"; ++ ++ case EXIT_EXCEPTION: ++ return "EXCEPTION"; + } + } + +diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h +index dc284aa..e923247 100644 +--- a/src/basic/exit-status.h ++++ b/src/basic/exit-status.h +@@ -70,6 +70,7 @@ enum { + EXIT_LOGS_DIRECTORY, /* 240 */ + EXIT_CONFIGURATION_DIRECTORY, + EXIT_NUMA_POLICY, ++ EXIT_EXCEPTION = 255, /* Whenever we want to propagate an abnormal/signal exit, in line with bash */ + }; + + typedef enum ExitStatusLevel { +-- +2.27.0 + diff --git a/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch b/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch new file mode 100644 index 0000000..026fc66 --- /dev/null +++ b/10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch @@ -0,0 +1,52 @@ +From dffb92b5520a4b539f0466d4161fcaacc6ba5ba8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 19 Apr 2022 11:34:27 +0800 +Subject: [PATCH] main: don't freeze PID 1 in containers, exit with + +--- + src/core/main.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index d897155..0aec5d1 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -139,7 +139,13 @@ static NUMAPolicy arg_numa_policy; + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); + +-_noreturn_ static void freeze_or_reboot(void) { ++_noreturn_ static void freeze_or_exit_or_reboot(void) { ++ /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the ++ * container manager, and thus inform it that something went wrong. */ ++ if (detect_container() > 0) { ++ log_emergency("Exiting PID 1..."); ++ exit(EXIT_EXCEPTION); ++ } + + if (arg_crash_reboot) { + log_notice("Rebooting in 10s..."); +@@ -247,7 +253,7 @@ _noreturn_ static void crash(int sig) { + } + } + +- freeze_or_reboot(); ++ freeze_or_exit_or_reboot(); + } + + static void install_crash_handler(void) { +@@ -2664,9 +2670,9 @@ finish: + if (error_message) + manager_status_printf(NULL, STATUS_TYPE_EMERGENCY, + ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL, +- "%s, freezing.", error_message); +- freeze_or_reboot(); ++ "%s.", error_message); ++ freeze_or_exit_or_reboot(); + } + + reset_arguments(); + return retval; +-- +2.27.0 + diff --git a/10004-Do-not-go-into-freeze-when-systemd-crashd.patch b/10004-Do-not-go-into-freeze-when-systemd-crashd.patch new file mode 100644 index 0000000..1cb12cc --- /dev/null +++ b/10004-Do-not-go-into-freeze-when-systemd-crashd.patch @@ -0,0 +1,103 @@ +From 64072aab92ff6489a2e460a9bdd1cfefa587264b Mon Sep 17 00:00:00 2001 +From: Yuanhong Peng +Date: Tue, 19 Apr 2022 13:36:09 +0800 +Subject: [PATCH] Do not go into freeze when systemd crashd + +--- + src/core/main.c | 41 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 0aec5d1..db91151 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -10,6 +11,7 @@ + #include + #include + #include ++#include + #include + #if HAVE_SECCOMP + #include +@@ -135,10 +137,41 @@ static sd_id128_t arg_machine_id; + static EmergencyAction arg_cad_burst_action; + static CPUSet arg_cpu_affinity; + static NUMAPolicy arg_numa_policy; ++static bool reexec_jmp_can = false; ++static bool reexec_jmp_inited = false; ++static sigjmp_buf reexec_jmp_buf; + + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); + ++static void reexec_handler(int sig) { ++ reexec_jmp_can = true; ++} ++ ++_noreturn_ static void freeze_wait_upgrade(void) { ++ struct sigaction sa; ++ sigset_t ss; ++ ++ sigemptyset(&ss); ++ sigaddset(&ss, SIGTERM); ++ sigprocmask(SIG_UNBLOCK, &ss, NULL); ++ ++ sa.sa_handler = reexec_handler; ++ sa.sa_flags = SA_RESTART; ++ sigaction(SIGTERM, &sa, NULL); ++ ++ log_error("freeze_wait_upgrade: %d\n", reexec_jmp_inited); ++ reexec_jmp_can = false; ++ while(1) { ++ usleep(10000); ++ if (reexec_jmp_inited && reexec_jmp_can) { ++ log_error("goto manager_reexecute.\n"); ++ siglongjmp(reexec_jmp_buf, 1); ++ } ++ waitpid(-1, NULL, WNOHANG); ++ } ++} ++ + _noreturn_ static void freeze_or_exit_or_reboot(void) { + /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the + * container manager, and thus inform it that something went wrong. */ +@@ -157,7 +190,8 @@ _noreturn_ static void freeze_or_exit_or_reboot(void) { + } + + log_emergency("Freezing execution."); +- freeze(); ++ freeze_wait_upgrade(); ++ + } + + _noreturn_ static void crash(int sig) { +@@ -1667,6 +1701,10 @@ static int invoke_main_loop( + assert(ret_switch_root_init); + assert(ret_error_message); + ++ reexec_jmp_inited = true; ++ if (sigsetjmp(reexec_jmp_buf, 1)) ++ goto manager_reexecute; ++ + for (;;) { + r = manager_loop(m); + if (r < 0) { +@@ -1709,6 +1747,7 @@ static int invoke_main_loop( + + case MANAGER_REEXECUTE: + ++manager_reexecute: + r = prepare_reexecute(m, &arg_serialization, ret_fds, false); + if (r < 0) { + *ret_error_message = "Failed to prepare for reexecution"; +-- +2.27.0 + diff --git a/10005-mount-setup-change-the-system-mount-propagation-to-s.patch b/10005-mount-setup-change-the-system-mount-propagation-to-s.patch new file mode 100644 index 0000000..fa95141 --- /dev/null +++ b/10005-mount-setup-change-the-system-mount-propagation-to-s.patch @@ -0,0 +1,62 @@ +From 0c7f29561634f9374c0d9042304f4d4caa4242f0 Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Tue, 19 Apr 2022 13:50:04 +0800 +Subject: [PATCH] mount-setup: change the system mount propagation to + +--- + src/core/main.c | 2 +- + src/core/mount-setup.c | 4 ++-- + src/core/mount-setup.h | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index db91151..81dae1c 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2519,7 +2519,7 @@ int main(int argc, char *argv[]) { + if (!skip_setup) + kmod_setup(); + +- r = mount_setup(loaded_policy); ++ r = mount_setup(loaded_policy, skip_setup); + if (r < 0) { + error_message = "Failed to mount API filesystems"; + goto finish; +diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c +index a659458..9f9f953 100644 +--- a/src/core/mount-setup.c ++++ b/src/core/mount-setup.c +@@ -400,7 +400,7 @@ static int relabel_cgroup_filesystems(void) { + } + #endif + +-int mount_setup(bool loaded_policy) { ++int mount_setup(bool loaded_policy, bool leave_propagation) { + int r = 0; + + r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy); +@@ -444,7 +444,7 @@ int mount_setup(bool loaded_policy) { + * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a + * container manager we assume the container manager knows what it is doing (for example, because it set up + * some directories with different propagation modes). */ +- if (detect_container() <= 0) ++ if (detect_container() <= 0 && !leave_propagation) + if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) + log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m"); + +diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h +index 43cd890..7a011b2 100644 +--- a/src/core/mount-setup.h ++++ b/src/core/mount-setup.h +@@ -4,7 +4,7 @@ + #include + + int mount_setup_early(void); +-int mount_setup(bool loaded_policy); ++int mount_setup(bool loaded_policy, bool leave_propagation); + + int mount_cgroup_controllers(char ***join_controllers); + +-- +2.27.0 + diff --git a/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch b/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch new file mode 100644 index 0000000..9a5fa6e --- /dev/null +++ b/10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch @@ -0,0 +1,26 @@ +From d449667a6a545a46647911838731e8e46a5a39ed Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 19 Apr 2022 13:56:39 +0800 +Subject: [PATCH] cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() + unsigned + +--- + src/basic/cgroup-util.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index 1210b38..76659c3 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -31,7 +31,7 @@ typedef enum CGroupController { + _CGROUP_CONTROLLER_INVALID = -1, + } CGroupController; + +-#define CGROUP_CONTROLLER_TO_MASK(c) (1 << (c)) ++#define CGROUP_CONTROLLER_TO_MASK(c) (1U << (c)) + + /* A bit mask of well known cgroup controllers */ + typedef enum CGroupMask { +-- +2.27.0 + diff --git a/10007-cgroup-update-only-siblings-that-got-realized-once.patch b/10007-cgroup-update-only-siblings-that-got-realized-once.patch new file mode 100644 index 0000000..068f21c --- /dev/null +++ b/10007-cgroup-update-only-siblings-that-got-realized-once.patch @@ -0,0 +1,46 @@ +From 841539281bed5187d2f773097eefb0bb3c5057ec Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 19 Apr 2022 14:03:12 +0800 +Subject: [PATCH] cgroup: update only siblings that got realized once + +--- + src/core/cgroup.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f02cc31..e0e0a98 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1980,7 +1980,16 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + Unit *slice; + + /* This adds the siblings of the specified unit and the siblings of all parent units to the cgroup +- * queue. (But neither the specified unit itself nor the parents.) */ ++ * queue. (But neither the specified unit itself nor the parents.) ++ * ++ * Propagation of realization "side-ways" (i.e. towards siblings) is in relevant on cgroup-v1 where ++ * scheduling become very weird if two units that own processes reside in the same slice, but one is ++ * realized in the "cpu" hierarchy and once is not (for example because one has CPUWeight= set and ++ * the other does not), because that means processes need to be scheduled against groups. Let's avoid ++ * this asymmetry by always ensuring that units below a slice that are realized at all are hence ++ * always realized in *all* their hierarchies, and it is sufficient for a unit's sibling to be ++ * realized for a unit to be realized too. */ ++ + + while ((slice = UNIT_DEREF(u->slice))) { + Iterator i; +@@ -1996,6 +2005,11 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(m))) + continue; + ++ /* We only enqueue siblings if they were realized once at least, in the main ++ * hierarchy. */ ++ if (!m->cgroup_realized) ++ continue; ++ + /* If the unit doesn't need any new controllers and has current ones realized, it + * doesn't need any changes. */ + if (unit_has_mask_realized(m, +-- +2.27.0 + diff --git a/10008-core-add-a-config-item-to-support-setting-the-value-.patch b/10008-core-add-a-config-item-to-support-setting-the-value-.patch new file mode 100644 index 0000000..272d61b --- /dev/null +++ b/10008-core-add-a-config-item-to-support-setting-the-value-.patch @@ -0,0 +1,120 @@ +From f21d63650318791f29f56dc26f23acb5b53620a6 Mon Sep 17 00:00:00 2001 +From:Yuanhong Peng +Date: Tue, 19 Apr 2022 14:13:49 +0800 +Subject: [PATCH] core: add a config item to support setting the value + +--- + src/core/main.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index 81dae1c..0712423 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -140,6 +140,7 @@ static NUMAPolicy arg_numa_policy; + static bool reexec_jmp_can = false; + static bool reexec_jmp_inited = false; + static sigjmp_buf reexec_jmp_buf; ++static bool arg_default_cpuset_clone_children = false; + + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); +@@ -527,6 +528,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + return 0; + + parse_path_argument_and_warn(value, false, &arg_watchdog_device); ++ ++ } else if (proc_cmdline_key_streq(key, "systemd.cpuset_clone_children") && value) { ++ ++ r = parse_boolean(value); ++ if (r < 0) ++ log_warning("Failed to parse cpuset_clone_children switch %s. Ignoring.", value); ++ else ++ arg_default_cpuset_clone_children = r; + + } else if (streq(key, "quiet") && !value) { + +@@ -756,6 +765,7 @@ static int parse_config_file(void) { + { "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting }, + { "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max }, + { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action }, ++ { "Manager", "DefaultCPUSetCloneChildren",config_parse_bool, 0, &arg_default_cpuset_clone_children }, + {} + }; + +@@ -1872,6 +1882,64 @@ static void log_execution_mode(bool *ret_first_boot) { + } + } + ++static bool is_use_triple_cgroup(void) { ++ const char * path ="/sys/fs/cgroup/cpuset"; ++ _cleanup_strv_free_ char **l = NULL; ++ char buf[128] = {0}; ++ int r; ++ ++ r = is_symlink(path); ++ if (r <= 0) ++ return false; ++ ++ r = readlink(path, buf, sizeof(buf)); ++ if (r < 0 || (unsigned int)r >= sizeof(buf)) ++ return false; ++ ++ buf[r] = '\0'; ++ l = strv_split(buf, ","); ++ if (!l) ++ return false; ++ ++ strv_sort(l); ++ if (strv_length(l) != 3) ++ return false; ++ ++ if (streq(l[0],"cpu") && streq(l[1], "cpuacct") && ++ streq(l[2], "cpuset")) { ++ log_debug(PACKAGE_STRING " use_triple_cgroup: %s", buf); ++ return true; ++ } ++ return false; ++} ++ ++static int ali_handle_cpuset_clone_children(void) ++{ ++ const char *file = "/sys/fs/cgroup/cpuset/cgroup.clone_children"; ++ _cleanup_free_ char *buf = NULL; ++ int r; ++ ++ r = read_one_line_file(file, &buf); ++ if (r < 0) { ++ log_warning_errno(r, "Cannot read %s: %m", file); ++ return r; ++ } ++ ++ if (streq(buf, "1") && arg_default_cpuset_clone_children) ++ return 0; ++ ++ if (streq(buf, "0") && (!arg_default_cpuset_clone_children)) ++ return 0; ++ ++ if (!is_use_triple_cgroup()) ++ return 0; ++ ++ r = write_string_file(file, one_zero(arg_default_cpuset_clone_children), 0); ++ log_info(PACKAGE_STRING " set %s to %s, ret=%d", file, one_zero(arg_default_cpuset_clone_children), r); ++ return r; ++} ++ ++ + static int initialize_runtime( + bool skip_setup, + struct rlimit *saved_rlimit_nofile, +@@ -1906,6 +1974,7 @@ static int initialize_runtime( + return r; + } + ++ ali_handle_cpuset_clone_children(); + status_welcome(); + hostname_setup(); + machine_id_setup(NULL, arg_machine_id, NULL); +-- +2.27.0 + diff --git a/10009-systemd-anolis-support-loongarch64.patch b/10009-systemd-anolis-support-loongarch64.patch new file mode 100644 index 0000000..b76c8e0 --- /dev/null +++ b/10009-systemd-anolis-support-loongarch64.patch @@ -0,0 +1,56 @@ +From c8b7c2b34bd451cd9d5904fc215ad14893008a03 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 19 Apr 2022 14:25:05 +0800 +Subject: [PATCH] support loongarch64 for systemd + +--- + src/basic/architecture.c | 3 +++ + src/basic/architecture.h | 4 ++++ + 2 files changed, 7 insertions(+) + +diff --git a/src/basic/architecture.c b/src/basic/architecture.c +index 85837b5..96bbf97 100644 +--- a/src/basic/architecture.c ++++ b/src/basic/architecture.c +@@ -118,6 +118,8 @@ int uname_architecture(void) { + #elif defined(__arc__) + { "arc", ARCHITECTURE_ARC }, + { "arceb", ARCHITECTURE_ARC_BE }, ++#elif defined(__loongarch64) ++ { "loongarch64", ARCHITECTURE_LOONGARCH64 }, + #else + #error "Please register your architecture here!" + #endif +@@ -173,6 +175,7 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = { + [ARCHITECTURE_RISCV64] = "riscv64", + [ARCHITECTURE_ARC] = "arc", + [ARCHITECTURE_ARC_BE] = "arc-be", ++ [ARCHITECTURE_LOONGARCH64] = "loongarch64", + }; + + DEFINE_STRING_TABLE_LOOKUP(architecture, int); +diff --git a/src/basic/architecture.h b/src/basic/architecture.h +index 443e890..22e9108 100644 +--- a/src/basic/architecture.h ++++ b/src/basic/architecture.h +@@ -44,6 +44,7 @@ enum { + ARCHITECTURE_RISCV64, + ARCHITECTURE_ARC, + ARCHITECTURE_ARC_BE, ++ ARCHITECTURE_LOONGARCH64, + _ARCHITECTURE_MAX, + _ARCHITECTURE_INVALID = -1 + }; +@@ -229,6 +230,9 @@ int uname_architecture(void); + # define native_architecture() ARCHITECTURE_ARC + # define LIB_ARCH_TUPLE "arc-linux" + # endif ++#elif defined(__loongarch64) ++# define native_architecture() ARCHITECTURE_LOONGARCH64 ++# define LIB_ARCH_TUPLE "loongarch64-linux-gnu" + #else + # error "Please register your architecture here!" + #endif +-- +2.27.0 + diff --git a/systemd.spec b/systemd.spec index 25e87ae..f509521 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1,3 +1,4 @@ +%define anolis_release .0.1 #global gitcommit 10e465b5321bd53c1fc59ffab27e724535c6bc0f %{?gitcommit:%global gitcommitshort %(c=%{gitcommit}; echo ${c:0:7})} @@ -13,7 +14,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 78%{?dist} +Release: 78%{anolis_release}%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1029,6 +1030,16 @@ Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch +Patch10000: 10000-core-fix-a-null-reference-case-in-load_from_path.patch +Patch10001: 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch +Patch10002: 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch +Patch10003: 10003-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch +Patch10004: 10004-Do-not-go-into-freeze-when-systemd-crashd.patch +Patch10005: 10005-mount-setup-change-the-system-mount-propagation-to-s.patch +Patch10006: 10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch +Patch10007: 10007-cgroup-update-only-siblings-that-got-realized-once.patch +Patch10008: 10008-core-add-a-config-item-to-support-setting-the-value-.patch +Patch10009: 10009-systemd-anolis-support-loongarch64.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1659,6 +1670,18 @@ fi %files tests -f .file-list-tests %changelog +* Tue Dec 26 2023 Yuanhong Peng - 239-78.0.1 +- core: fix a null reference case in load_from_path() +- sysctl: Don't pass null directive argument to '%s' +- exit-status: introduce EXIT_EXCEPTION mapping to 255 +- main: don't freeze PID 1 in containers, exit with non-zero instead +- Do not go into freeze when systemd crashd +- mount-setup: change the system mount propagation to shared by default only at bootup +- cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() unsigned +- cgroup: update only siblings that got realized once +- core: add a config item to support setting the value of cpuset.clone_children when systemd is starting +- support loongarch for systemd + * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) - logind: reset session leader if we know for a fact that it is gone (#2158167) -- Gitee From 7170d615047abc0b729aff056d817e01aa133e2c Mon Sep 17 00:00:00 2001 From: Yuanhong Peng Date: Wed, 18 May 2022 10:24:07 +0800 Subject: [PATCH 03/11] test-catalog: Fix coredump when compiled under GCC10 Signed-off-by: Yuanhong Peng --- ...x-coredump-when-compiled-under-GCC10.patch | 56 +++++++++++++++++++ systemd.spec | 2 + 2 files changed, 58 insertions(+) create mode 100644 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch diff --git a/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch b/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch new file mode 100644 index 0000000..d4054b4 --- /dev/null +++ b/10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch @@ -0,0 +1,56 @@ +From 5209a26aa917aa54b09ee18394ad46ee601e77be Mon Sep 17 00:00:00 2001 +From: Yuanhong Peng +Date: Tue, 17 May 2022 21:34:34 +0800 +Subject: [PATCH] test-catalog: Fix coredump when compiled under GCC10 + +According to the documentation: +https://gcc.gnu.org/gcc-9/porting_to.html#complit: + +The `catalog_dirs` produced by STRV_MAKE(..) marco relies on +the extended lifetime feature which is fixed by GCC9. + +Signed-off-by: Yuanhong Peng +--- + src/journal/test-catalog.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c +index 0c4da29..2ce92af 100644 +--- a/src/journal/test-catalog.c ++++ b/src/journal/test-catalog.c +@@ -201,7 +201,8 @@ static void test_catalog_file_lang(void) { + + int main(int argc, char *argv[]) { + _cleanup_(unlink_tempfilep) char database[] = "/tmp/test-catalog.XXXXXX"; +- _cleanup_free_ char *text = NULL, *catalog_dir = NULL; ++ _cleanup_free_ char *text = NULL; ++ char *catalog_dir = CATALOG_DIR; + int r; + + setlocale(LC_ALL, "de_DE.UTF-8"); +@@ -214,10 +215,9 @@ int main(int argc, char *argv[]) { + * If it is not, e.g. installed by systemd-tests package, then use installed catalogs. */ + if (test_is_running_from_builddir(NULL)) { + assert_se(catalog_dir = path_join(NULL, ABS_BUILD_DIR, "catalog")); +- catalog_dirs = STRV_MAKE(catalog_dir); +- } else +- catalog_dirs = STRV_MAKE(CATALOG_DIR); ++ } + ++ catalog_dirs = STRV_MAKE(catalog_dir); + assert_se(access(catalog_dirs[0], F_OK) >= 0); + log_notice("Using catalog directory '%s'", catalog_dirs[0]); + +@@ -242,5 +242,9 @@ int main(int argc, char *argv[]) { + assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0); + printf(">>>%s<<<\n", text); + ++ /* Only in this case, catalog_dir is malloced */ ++ if (test_is_running_from_builddir(NULL)) ++ free(catalog_dir); ++ + return 0; + } +-- +2.27.0 + diff --git a/systemd.spec b/systemd.spec index f509521..59481d4 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1040,6 +1040,7 @@ Patch10006: 10006-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch Patch10007: 10007-cgroup-update-only-siblings-that-got-realized-once.patch Patch10008: 10008-core-add-a-config-item-to-support-setting-the-value-.patch Patch10009: 10009-systemd-anolis-support-loongarch64.patch +Patch10010: 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1681,6 +1682,7 @@ fi - cgroup: update only siblings that got realized once - core: add a config item to support setting the value of cpuset.clone_children when systemd is starting - support loongarch for systemd +- test-catalog: Fix coredump when compiled under GCC10 * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From 2492dffb565cf619bfe08ac4d296e6e13190be1d Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Tue, 26 Jul 2022 22:05:44 +0800 Subject: [PATCH 04/11] hwdb: add Iluvatar CoreX https://bugzilla.openanolis.cn/show_bug.cgi?id=1740 Signed-off-by: Liwei Ge --- 10011-hwdb-add-Iluvatar-CoreX.patch | 44 +++++++++++++++++++++++++++++ systemd.spec | 2 ++ 2 files changed, 46 insertions(+) create mode 100644 10011-hwdb-add-Iluvatar-CoreX.patch diff --git a/10011-hwdb-add-Iluvatar-CoreX.patch b/10011-hwdb-add-Iluvatar-CoreX.patch new file mode 100644 index 0000000..e08657c --- /dev/null +++ b/10011-hwdb-add-Iluvatar-CoreX.patch @@ -0,0 +1,44 @@ +From 28e47526dce925e6f32cf79825d38fd10e1f442a Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 26 Jul 2022 22:01:58 +0800 +Subject: [PATCH] hwdb: add Iluvatar CoreX + +Signed-off-by: rpm-build +--- + hwdb/20-pci-vendor-model.hwdb | 6 ++++++ + hwdb/pci.ids | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/hwdb/20-pci-vendor-model.hwdb b/hwdb/20-pci-vendor-model.hwdb +index 0020046..78926f8 100644 +--- a/hwdb/20-pci-vendor-model.hwdb ++++ b/hwdb/20-pci-vendor-model.hwdb +@@ -71141,6 +71141,12 @@ pci:v00001EEC* + pci:v00001EFB* + ID_VENDOR_FROM_DATABASE=Flexxon Pte Ltd + ++pci:v00001E3E* ++ ID_VENDOR_FROM_DATABASE=Iluvatar CoreX ++ ++pci:v00001E3Ed00000001* ++ ID_MODEL_FROM_DATABASE=Iluvatar BI-V100 ++ + pci:v00001FC0* + ID_VENDOR_FROM_DATABASE=Ascom (Finland) Oy + +diff --git a/hwdb/pci.ids b/hwdb/pci.ids +index 40ee143..d6661c7 100644 +--- a/hwdb/pci.ids ++++ b/hwdb/pci.ids +@@ -21543,6 +21543,8 @@ + 0003 alst4x + 1dfc JSC NT-COM + 1181 TDM 8 Port E1/T1/J1 Adapter ++1e3e Iluvatar CoreX ++ 0001 Iluvatar BI-V100 + # nee Tumsan Oy + 1fc0 Ascom (Finland) Oy + 0300 E2200 Dual E1/Rawpipe Card +-- +2.27.0 + diff --git a/systemd.spec b/systemd.spec index 59481d4..80dc6f6 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1041,6 +1041,7 @@ Patch10007: 10007-cgroup-update-only-siblings-that-got-realized-once.patch Patch10008: 10008-core-add-a-config-item-to-support-setting-the-value-.patch Patch10009: 10009-systemd-anolis-support-loongarch64.patch Patch10010: 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch +Patch10011: 10011-hwdb-add-Iluvatar-CoreX.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1683,6 +1684,7 @@ fi - core: add a config item to support setting the value of cpuset.clone_children when systemd is starting - support loongarch for systemd - test-catalog: Fix coredump when compiled under GCC10 +- add Iluvatar CoreX pci id(Liwei Ge) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From dc69c8c6c0fc6cd7da3176d8fb252618709e1bf8 Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Thu, 22 Sep 2022 10:38:05 +0800 Subject: [PATCH 05/11] seccomp: add loongarch support --- 10012-seccomp-add-loongarch-support.patch | 79 +++++++++++++++++++++++ systemd.spec | 4 +- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 10012-seccomp-add-loongarch-support.patch diff --git a/10012-seccomp-add-loongarch-support.patch b/10012-seccomp-add-loongarch-support.patch new file mode 100644 index 0000000..69b1b90 --- /dev/null +++ b/10012-seccomp-add-loongarch-support.patch @@ -0,0 +1,79 @@ +From 1894533699f7e01c80e896c5d022275777344492 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 22 Sep 2022 10:33:54 +0800 +Subject: [PATCH] seccomp: add loongarch support + +--- + src/shared/seccomp-util.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c +index c57c409..63a875c 100644 +--- a/src/shared/seccomp-util.c ++++ b/src/shared/seccomp-util.c +@@ -42,6 +42,8 @@ const uint32_t seccomp_local_archs[] = { + SCMP_ARCH_AARCH64, /* native */ + #elif defined(__arm__) + SCMP_ARCH_ARM, ++#elif defined(__loongarch__) ++ SCMP_ARCH_LOONGARCH64, + #elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32 + SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS, /* native */ +@@ -136,6 +138,10 @@ const char* seccomp_arch_to_string(uint32_t c) { + return "s390"; + case SCMP_ARCH_S390X: + return "s390x"; ++#if defined(__loongarch__) ++ case SCMP_ARCH_LOONGARCH64: ++ return "loongarch64"; ++#endif + default: + return NULL; + } +@@ -181,6 +187,10 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) { + *ret = SCMP_ARCH_S390; + else if (streq(n, "s390x")) + *ret = SCMP_ARCH_S390X; ++#if defined(__loongarch__) ++ else if (streq(n, "loongarch64")) ++ *ret = SCMP_ARCH_LOONGARCH64; ++#endif + else + return -EINVAL; + +@@ -1209,6 +1219,11 @@ int seccomp_protect_sysctl(void) { + if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64)) + /* No _sysctl syscall */ + continue; ++#if defined(__loongarch__) ++ if (IN_SET(arch, SCMP_ARCH_LOONGARCH64)) ++ /* No _sysctl syscall */ ++ continue; ++#endif + + r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW); + if (r < 0) +@@ -1267,6 +1282,9 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + case SCMP_ARCH_PPC: + case SCMP_ARCH_PPC64: + case SCMP_ARCH_PPC64LE: ++#if defined(__loongarch__) ++ case SCMP_ARCH_LOONGARCH64: ++#endif + default: + /* These we either know we don't support (i.e. are the ones that do use socketcall()), or we + * don't know */ +@@ -1543,6 +1561,9 @@ int seccomp_memory_deny_write_execute(void) { + case SCMP_ARCH_X86_64: + case SCMP_ARCH_X32: + case SCMP_ARCH_AARCH64: ++#if defined(__loongarch__) ++ case SCMP_ARCH_LOONGARCH64: ++#endif + filter_syscall = SCMP_SYS(mmap); /* amd64, x32, and arm64 have only mmap */ + shmat_syscall = SCMP_SYS(shmat); + break; +-- +2.27.0 + diff --git a/systemd.spec b/systemd.spec index 80dc6f6..0318246 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1042,6 +1042,7 @@ Patch10008: 10008-core-add-a-config-item-to-support-setting-the-value-.patch Patch10009: 10009-systemd-anolis-support-loongarch64.patch Patch10010: 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch Patch10011: 10011-hwdb-add-Iluvatar-CoreX.patch +Patch10012: 10012-seccomp-add-loongarch-support.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1684,7 +1685,8 @@ fi - core: add a config item to support setting the value of cpuset.clone_children when systemd is starting - support loongarch for systemd - test-catalog: Fix coredump when compiled under GCC10 -- add Iluvatar CoreX pci id(Liwei Ge) +- add Iluvatar CoreX pci id (Liwei Ge) +- seccomp: add loongarch64 support (Liwei Ge) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From 2ad538a94ac051dabfc190c88f0b8ee17b456ff3 Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Tue, 6 Dec 2022 16:16:34 +0800 Subject: [PATCH 06/11] seccomp: remove loongarch condition since seccomp is fit into loongarch64 now these condition code cloud be removed --- 10012-seccomp-add-loongarch-support.patch | 106 +++++++++++++--------- systemd.spec | 1 + 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/10012-seccomp-add-loongarch-support.patch b/10012-seccomp-add-loongarch-support.patch index 69b1b90..6aba34f 100644 --- a/10012-seccomp-add-loongarch-support.patch +++ b/10012-seccomp-add-loongarch-support.patch @@ -1,14 +1,14 @@ -From 1894533699f7e01c80e896c5d022275777344492 Mon Sep 17 00:00:00 2001 +From 4c7025f5198be3d055c0e5ad68d364a57e8a7dcc Mon Sep 17 00:00:00 2001 From: rpm-build Date: Thu, 22 Sep 2022 10:33:54 +0800 Subject: [PATCH] seccomp: add loongarch support --- - src/shared/seccomp-util.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) + src/shared/seccomp-util.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c -index c57c409..63a875c 100644 +index c57c409..1eec0be 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -42,6 +42,8 @@ const uint32_t seccomp_local_archs[] = { @@ -20,60 +20,82 @@ index c57c409..63a875c 100644 #elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32 SCMP_ARCH_MIPSEL, SCMP_ARCH_MIPS, /* native */ -@@ -136,6 +138,10 @@ const char* seccomp_arch_to_string(uint32_t c) { - return "s390"; - case SCMP_ARCH_S390X: - return "s390x"; -+#if defined(__loongarch__) +@@ -114,6 +116,8 @@ const char* seccomp_arch_to_string(uint32_t c) { + return "arm"; + case SCMP_ARCH_AARCH64: + return "arm64"; + case SCMP_ARCH_LOONGARCH64: + return "loongarch64"; -+#endif - default: - return NULL; - } -@@ -181,6 +187,10 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) { - *ret = SCMP_ARCH_S390; - else if (streq(n, "s390x")) - *ret = SCMP_ARCH_S390X; -+#if defined(__loongarch__) + case SCMP_ARCH_MIPS: + return "mips"; + case SCMP_ARCH_MIPS64: +@@ -159,6 +163,8 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) { + *ret = SCMP_ARCH_ARM; + else if (streq(n, "arm64")) + *ret = SCMP_ARCH_AARCH64; + else if (streq(n, "loongarch64")) + *ret = SCMP_ARCH_LOONGARCH64; -+#endif - else - return -EINVAL; + else if (streq(n, "mips")) + *ret = SCMP_ARCH_MIPS; + else if (streq(n, "mips64")) +@@ -1206,7 +1212,7 @@ int seccomp_protect_sysctl(void) { -@@ -1209,6 +1219,11 @@ int seccomp_protect_sysctl(void) { - if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64)) + log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch)); + +- if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64)) ++ if (IN_SET(arch, SCMP_ARCH_X32, SCMP_ARCH_AARCH64, SCMP_ARCH_LOONGARCH64)) /* No _sysctl syscall */ continue; -+#if defined(__loongarch__) -+ if (IN_SET(arch, SCMP_ARCH_LOONGARCH64)) -+ /* No _sysctl syscall */ -+ continue; -+#endif - r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW); - if (r < 0) -@@ -1267,6 +1282,9 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { - case SCMP_ARCH_PPC: - case SCMP_ARCH_PPC64: - case SCMP_ARCH_PPC64LE: -+#if defined(__loongarch__) +@@ -1251,6 +1257,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + case SCMP_ARCH_X32: + case SCMP_ARCH_ARM: + case SCMP_ARCH_AARCH64: + case SCMP_ARCH_LOONGARCH64: -+#endif - default: - /* These we either know we don't support (i.e. are the ones that do use socketcall()), or we - * don't know */ -@@ -1543,6 +1561,9 @@ int seccomp_memory_deny_write_execute(void) { + case SCMP_ARCH_MIPSEL64N32: + case SCMP_ARCH_MIPS64N32: + case SCMP_ARCH_MIPSEL64: +@@ -1496,7 +1503,7 @@ static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp, + } + + /* For known architectures, check that syscalls are indeed defined or not. */ +-#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) ++#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch__) + assert_cc(SCMP_SYS(shmget) > 0); + assert_cc(SCMP_SYS(shmat) > 0); + assert_cc(SCMP_SYS(shmdt) > 0); +@@ -1543,13 +1550,14 @@ int seccomp_memory_deny_write_execute(void) { case SCMP_ARCH_X86_64: case SCMP_ARCH_X32: case SCMP_ARCH_AARCH64: -+#if defined(__loongarch__) + case SCMP_ARCH_LOONGARCH64: -+#endif filter_syscall = SCMP_SYS(mmap); /* amd64, x32, and arm64 have only mmap */ shmat_syscall = SCMP_SYS(shmat); break; + + /* Please add more definitions here, if you port systemd to other architectures! */ + +-#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) ++#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__loongarch__) + #warning "Consider adding the right mmap() syscall definitions here!" + #endif + } +@@ -1573,13 +1581,13 @@ int seccomp_memory_deny_write_execute(void) { + if (r < 0) + continue; + } +- ++ if (!IN_SET(arch, SCMP_ARCH_LOONGARCH64)){ + r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(mprotect), + 1, + SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC)); + if (r < 0) + continue; +- ++ } + #ifdef __NR_pkey_mprotect + r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(pkey_mprotect), + 1, -- 2.27.0 diff --git a/systemd.spec b/systemd.spec index 0318246..27c47c5 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1687,6 +1687,7 @@ fi - test-catalog: Fix coredump when compiled under GCC10 - add Iluvatar CoreX pci id (Liwei Ge) - seccomp: add loongarch64 support (Liwei Ge) +- seccomp: remove loongarch64 switch(Liwei Ge) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From e33c33abec6a0c05c317d2769e62abd984ac6a18 Mon Sep 17 00:00:00 2001 From: yuanhui Date: Mon, 6 Mar 2023 17:48:29 +0800 Subject: [PATCH 07/11] umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed success Signed-off-by: yuanhui --- ...FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch | 66 +++++++++++++++++++ systemd.spec | 2 + 2 files changed, 68 insertions(+) create mode 100644 0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch diff --git a/0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch b/0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch new file mode 100644 index 0000000..c24ff51 --- /dev/null +++ b/0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch @@ -0,0 +1,66 @@ +From b877c3b06f15a025748b9f09621ddf1bd00cacce Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 20 Dec 2019 17:58:03 +0100 +Subject: [PATCH] umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed + success + +Fixes: #14410 +Replaces: #14386 + +--- + systemd-239/src/core/umount.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/src/core/umount.c b/src/core/umount.c +index 241fe6f..4400b3c 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -334,23 +334,38 @@ static int dm_list_get(MountPoint **head) { + + static int delete_loopback(const char *device) { + _cleanup_close_ int fd = -1; +- int r; ++ struct loop_info64 info; + + assert(device); + + fd = open(device, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return errno == ENOENT ? 0 : -errno; ++ ++ if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { ++ if (errno == ENXIO) /* Nothing bound, didn't do anything */ ++ return 0; ++ ++ return -errno; ++ } + +- r = ioctl(fd, LOOP_CLR_FD, 0); +- if (r >= 0) ++ if (ioctl(fd, LOOP_GET_STATUS64, &info) < 0) { ++ /* If the LOOP_CLR_FD above succeeded we'll see ENXIO here. */ ++ if (errno == ENXIO) ++ log_debug("Successfully detached loopback device %s.", device); ++ else ++ log_debug_errno(errno, "Failed to invoke LOOP_GET_STATUS64 on loopback device %s, ignoring: %m", device); /* the LOOP_CLR_FD at least worked, let's hope for the best */ + return 1; ++ } + +- /* ENXIO: not bound, so no error */ +- if (errno == ENXIO) +- return 0; ++ /* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing ++ * anything. Very confusing. Let's hence not claim we did anything in this case. */ ++ if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) ++ log_debug("Successfully called LOOP_CLR_FD on a loopback device %s with autoclear set, which is a NOP.", device); ++ else ++ log_debug("Weird, LOOP_CLR_FD succeeded but the device is still attached on %s.", device); + +- return -errno; ++ return -EBUSY; /* Nothing changed, the device is still attached, hence it apparently is still busy */; + } + + static int delete_dm(dev_t devnum) { +-- +2.31.1 + diff --git a/systemd.spec b/systemd.spec index 27c47c5..05cd3aa 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1030,6 +1030,7 @@ Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch +Patch0980: 0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch Patch10000: 10000-core-fix-a-null-reference-case-in-load_from_path.patch Patch10001: 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch Patch10002: 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch @@ -1688,6 +1689,7 @@ fi - add Iluvatar CoreX pci id (Liwei Ge) - seccomp: add loongarch64 support (Liwei Ge) - seccomp: remove loongarch64 switch(Liwei Ge) +- umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed success(yuanhui) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From c27e6417695e586ab957708ca57399ac000c0742 Mon Sep 17 00:00:00 2001 From: Guorui Yu Date: Wed, 2 Aug 2023 22:44:03 +0800 Subject: [PATCH 08/11] cryptsetup: if keyfile is specified as AF_UNIX socket in the fs, connect to it, and read key data from it Signed-off-by: Guorui Yu --- ...ding-a-full-file-into-memory-refuse-.patch | 120 ++++++++ ...explicit_bzero_safe-for-explicit-mem.patch | 61 ++++ ...util-introduce-erase_and_free-helper.patch | 48 ++++ ...READ_FULL_FILE_SECURE-flag-for-readi.patch | 207 +++++++++++++ ...roduce-warn_file_is_world_accessible.patch | 67 +++++ ...l_file_full-also-warns-when-file-is-.patch | 64 +++++ ...x-memory-leak-if-READ_FULL_FILE_SECU.patch | 30 ++ ...icit-flag-for-generating-world-execu.patch | 44 +++ ..._fd-parameter-to-read_full_file_full.patch | 142 +++++++++ ...ort-for-read_full_file-on-AF_UNIX-st.patch | 271 ++++++++++++++++++ ...READ_FULL_FILE_CONNECT_SOCKET-to-all.patch | 181 ++++++++++++ ...ad_full_file_full-to-read-from-offse.patch | 246 ++++++++++++++++ ...-cryptsetup-s-main-key-file-logic-ov.patch | 95 ++++++ systemd.spec | 26 ++ 14 files changed, 1602 insertions(+) create mode 100644 10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch create mode 100644 10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch create mode 100644 10015-util-introduce-erase_and_free-helper.patch create mode 100644 10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch create mode 100644 10017-fileio-introduce-warn_file_is_world_accessible.patch create mode 100644 10018-fileio-read_full_file_full-also-warns-when-file-is-.patch create mode 100644 10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch create mode 100644 10020-fileio-add-explicit-flag-for-generating-world-execu.patch create mode 100644 10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch create mode 100644 10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch create mode 100644 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch create mode 100644 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch create mode 100644 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch diff --git a/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch b/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch new file mode 100644 index 0000000..f2eeed5 --- /dev/null +++ b/10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch @@ -0,0 +1,120 @@ +From 9f181efdd59bd3e9134cf94007953562ca8b57fa Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Sat, 15 Dec 2018 12:25:32 +0100 +Subject: [PATCH] fileio: when reading a full file into memory, refuse inner + NUL bytes + +Just some extra care to avoid any ambiguities in what we read. + +(cherry picked from commit beb90929913354eec50c3524086fe70d14f97e2f) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 25 +++++++++++++++++++------ + src/test/test-unit-file.c | 10 +++++----- + 2 files changed, 24 insertions(+), 11 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 733fb42463..9fef97ff0c 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -383,16 +383,20 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re + return 0; + } + +-int read_full_stream(FILE *f, char **contents, size_t *size) { ++int read_full_stream( ++ FILE *f, ++ char **ret_contents, ++ size_t *ret_size) { ++ + _cleanup_free_ char *buf = NULL; + struct stat st; + size_t n, l; + int fd; + + assert(f); +- assert(contents); ++ assert(ret_contents); + +- n = LINE_MAX; ++ n = LINE_MAX; /* Start size */ + + fd = fileno(f); + if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's +@@ -448,11 +452,20 @@ int read_full_stream(FILE *f, char **contents, size_t *size) { + n = MIN(n * 2, READ_FULL_BYTES_MAX); + } + ++ if (!ret_size) { ++ /* Safety check: if the caller doesn't want to know the size of what we just read it will rely on the ++ * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise ++ * there'd be ambiguity about what we just read. */ ++ ++ if (memchr(buf, 0, l)) ++ return -EBADMSG; ++ } ++ + buf[l] = 0; +- *contents = TAKE_PTR(buf); ++ *ret_contents = TAKE_PTR(buf); + +- if (size) +- *size = l; ++ if (ret_size) ++ *ret_size = l; + + return 0; + } +diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c +index 09b0179fa1..e64a27dd39 100644 +--- a/src/test/test-unit-file.c ++++ b/src/test/test-unit-file.c +@@ -532,7 +532,7 @@ static void test_load_env_file_1(void) { + + fd = mkostemp_safe(name); + assert_se(fd >= 0); +- assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1)); ++ assert_se(write(fd, env_file_1, strlen(env_file_1)) == strlen(env_file_1)); + + r = load_env_file(NULL, name, NULL, &data); + assert_se(r == 0); +@@ -554,7 +554,7 @@ static void test_load_env_file_2(void) { + + fd = mkostemp_safe(name); + assert_se(fd >= 0); +- assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2)); ++ assert_se(write(fd, env_file_2, strlen(env_file_2)) == strlen(env_file_2)); + + r = load_env_file(NULL, name, NULL, &data); + assert_se(r == 0); +@@ -571,7 +571,7 @@ static void test_load_env_file_3(void) { + + fd = mkostemp_safe(name); + assert_se(fd >= 0); +- assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3)); ++ assert_se(write(fd, env_file_3, strlen(env_file_3)) == strlen(env_file_3)); + + r = load_env_file(NULL, name, NULL, &data); + assert_se(r == 0); +@@ -586,7 +586,7 @@ static void test_load_env_file_4(void) { + + fd = mkostemp_safe(name); + assert_se(fd >= 0); +- assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4)); ++ assert_se(write(fd, env_file_4, strlen(env_file_4)) == strlen(env_file_4)); + + r = load_env_file(NULL, name, NULL, &data); + assert_se(r == 0); +@@ -605,7 +605,7 @@ static void test_load_env_file_5(void) { + + fd = mkostemp_safe(name); + assert_se(fd >= 0); +- assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); ++ assert_se(write(fd, env_file_5, strlen(env_file_5)) == strlen(env_file_5)); + + r = load_env_file(NULL, name, NULL, &data); + assert_se(r == 0); +-- +2.39.1 + diff --git a/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch b/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch new file mode 100644 index 0000000..c0ec4be --- /dev/null +++ b/10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch @@ -0,0 +1,61 @@ +From 17037ec625fca9e9a473a33954d011065f0088e3 Mon Sep 17 00:00:00 2001 +From: Guorui Yu +Date: Fri, 23 Jun 2023 13:01:24 +0800 +Subject: [PATCH] util: introduce explicit_bzero_safe for explicit memset + +(cherry picked from commit f441ae81ef70e9bdfddbb9e0a276bbb8ca2151d4) + +Signed-off-by: Guorui Yu +--- + src/basic/util.c | 18 ++++++++++++++++++ + src/basic/util.h | 11 +++++++++++ + 2 files changed, 29 insertions(+) + +diff --git a/src/basic/util.c b/src/basic/util.c +index 548e3652cc..bdfaca4aed 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -684,3 +684,21 @@ void disable_coredumps(void) { + if (r < 0) + log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m"); + } ++ ++#if !HAVE_EXPLICIT_BZERO ++/* ++ * The pointer to memset() is volatile so that compiler must de-reference the pointer and can't assume that ++ * it points to any function in particular (such as memset(), which it then might further "optimize"). This ++ * approach is inspired by openssl's crypto/mem_clr.c. ++ */ ++typedef void *(*memset_t)(void *,int,size_t); ++ ++static volatile memset_t memset_func = memset; ++ ++void* explicit_bzero_safe(void *p, size_t l) { ++ if (l > 0) ++ memset_func(p, '\0', l); ++ ++ return p; ++} ++#endif +diff --git a/src/basic/util.h b/src/basic/util.h +index 195f02cf5f..ab3314f82e 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -240,3 +240,14 @@ int version(void); + int str_verscmp(const char *s1, const char *s2); + + void disable_coredumps(void); ++ ++#if HAVE_EXPLICIT_BZERO ++static inline void* explicit_bzero_safe(void *p, size_t l) { ++ if (l > 0) ++ explicit_bzero(p, l); ++ ++ return p; ++} ++#else ++void *explicit_bzero_safe(void *p, size_t l); ++#endif +-- +2.39.1 + diff --git a/10015-util-introduce-erase_and_free-helper.patch b/10015-util-introduce-erase_and_free-helper.patch new file mode 100644 index 0000000..43c42fc --- /dev/null +++ b/10015-util-introduce-erase_and_free-helper.patch @@ -0,0 +1,48 @@ +From 7c48fe64e3f1cdc61d9191d5e004d56d5244aa2c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 8 Aug 2019 19:53:17 +0200 +Subject: [PATCH] util: introduce erase_and_free() helper + +(cherry picked from commit a20dda788d5a0f3b300e0d8bb34e45be335e2915) + +Signed-off-by: Guorui Yu +--- + src/basic/util.h | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index ab3314f82e..4f4877b6b0 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -251,3 +252,20 @@ static inline void* explicit_bzero_safe(void *p, size_t l) { + #else + void *explicit_bzero_safe(void *p, size_t l); + #endif ++ ++static inline void* erase_and_free(void *p) { ++ size_t l; ++ ++ if (!p) ++ return NULL; ++ ++ l = malloc_usable_size(p); ++ explicit_bzero_safe(p, l); ++ free(p); ++ ++ return NULL; ++} ++ ++static inline void erase_and_freep(void *p) { ++ erase_and_free(*(void**) p); ++} +-- +2.39.1 + diff --git a/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch b/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch new file mode 100644 index 0000000..a37d579 --- /dev/null +++ b/10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch @@ -0,0 +1,207 @@ +From bc781489901fc6447cbd27b8d33f4f4439d6a5db Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 8 Apr 2019 02:22:40 +0900 +Subject: [PATCH] util: introduce READ_FULL_FILE_SECURE flag for reading secure + data + +(cherry picked from commit e0721f97b05c0a5f782233711ea95c1e02ccba44) + +[Guorui Yu: include util.h for explicit_bzero_safe] +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 68 ++++++++++++++++++++++++++++++++-------------- + src/basic/fileio.h | 16 +++++++++-- + 2 files changed, 60 insertions(+), 24 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 9fef97ff0c..cf7c92ebc7 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -35,6 +35,7 @@ + #include "time-util.h" + #include "umask-util.h" + #include "utf8.h" ++#include "util.h" + + #define READ_FULL_BYTES_MAX (4U*1024U*1024U) + +@@ -383,26 +384,27 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re + return 0; + } + +-int read_full_stream( ++int read_full_stream_full( + FILE *f, ++ ReadFullFileFlags flags, + char **ret_contents, + size_t *ret_size) { + + _cleanup_free_ char *buf = NULL; + struct stat st; +- size_t n, l; +- int fd; ++ size_t n, n_next, l; ++ int fd, r; + + assert(f); + assert(ret_contents); + +- n = LINE_MAX; /* Start size */ ++ n_next = LINE_MAX; /* Start size */ + + fd = fileno(f); + if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's + * optimize our buffering) */ + +- if (fstat(fileno(f), &st) < 0) ++ if (fstat(fd, &st) < 0) + return -errno; + + if (S_ISREG(st.st_mode)) { +@@ -415,27 +417,41 @@ int read_full_stream( + * to read here by one, so that the first read attempt already + * makes us notice the EOF. */ + if (st.st_size > 0) +- n = st.st_size + 1; ++ n_next = st.st_size + 1; + } + } + +- l = 0; ++ n = l = 0; + for (;;) { + char *t; + size_t k; + +- t = realloc(buf, n + 1); +- if (!t) +- return -ENOMEM; ++ if (flags & READ_FULL_FILE_SECURE) { ++ t = malloc(n_next + 1); ++ if (!t) { ++ r = -ENOMEM; ++ goto finalize; ++ } ++ memcpy_safe(t, buf, n); ++ explicit_bzero_safe(buf, n); ++ } else { ++ t = realloc(buf, n_next + 1); ++ if (!t) ++ return -ENOMEM; ++ } + + buf = t; ++ n = n_next; ++ + errno = 0; + k = fread(buf + l, 1, n - l, f); + if (k > 0) + l += k; + +- if (ferror(f)) +- return errno > 0 ? -errno : -EIO; ++ if (ferror(f)) { ++ r = errno > 0 ? -errno : -EIO; ++ goto finalize; ++ } + + if (feof(f)) + break; +@@ -446,10 +462,12 @@ int read_full_stream( + assert(l == n); + + /* Safety check */ +- if (n >= READ_FULL_BYTES_MAX) +- return -E2BIG; ++ if (n >= READ_FULL_BYTES_MAX) { ++ r = -E2BIG; ++ goto finalize; ++ } + +- n = MIN(n * 2, READ_FULL_BYTES_MAX); ++ n_next = MIN(n * 2, READ_FULL_BYTES_MAX); + } + + if (!ret_size) { +@@ -457,8 +475,10 @@ int read_full_stream( + * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise + * there'd be ambiguity about what we just read. */ + +- if (memchr(buf, 0, l)) +- return -EBADMSG; ++ if (memchr(buf, 0, l)) { ++ r = -EBADMSG; ++ goto finalize; ++ } + } + + buf[l] = 0; +@@ -468,21 +488,27 @@ int read_full_stream( + *ret_size = l; + + return 0; ++ ++finalize: ++ if (flags & READ_FULL_FILE_SECURE) ++ explicit_bzero_safe(buf, n); ++ ++ return r; + } + +-int read_full_file(const char *fn, char **contents, size_t *size) { ++int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; + +- assert(fn); ++ assert(filename); + assert(contents); + +- f = fopen(fn, "re"); ++ f = fopen(filename, "re"); + if (!f) + return -errno; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + +- return read_full_stream(f, contents, size); ++ return read_full_stream_full(f, flags, contents, size); + } + + static int parse_env_file_internal( +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index c6ad375b8d..06649ef7e6 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -24,6 +24,10 @@ typedef enum { + + } WriteStringFileFlags; + ++typedef enum { ++ READ_FULL_FILE_SECURE = 1 << 0, ++} ReadFullFileFlags; ++ + int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); + static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { + return write_string_stream_ts(f, line, flags, NULL); +@@ -35,9 +39,15 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin + + int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); + +-int read_one_line_file(const char *fn, char **line); +-int read_full_file(const char *fn, char **contents, size_t *size); +-int read_full_stream(FILE *f, char **contents, size_t *size); ++int read_one_line_file(const char *filename, char **line); ++int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); ++static inline int read_full_file(const char *filename, char **contents, size_t *size) { ++ return read_full_file_full(filename, 0, contents, size); ++} ++int read_full_stream_full(FILE *f, ReadFullFileFlags flags, char **contents, size_t *size); ++static inline int read_full_stream(FILE *f, char **contents, size_t *size) { ++ return read_full_stream_full(f, 0, contents, size); ++} + int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); + + int verify_file(const char *fn, const char *blob, bool accept_extra_nl); +-- +2.39.1 + diff --git a/10017-fileio-introduce-warn_file_is_world_accessible.patch b/10017-fileio-introduce-warn_file_is_world_accessible.patch new file mode 100644 index 0000000..02f9518 --- /dev/null +++ b/10017-fileio-introduce-warn_file_is_world_accessible.patch @@ -0,0 +1,67 @@ +From e4c4f0bc712e43776c4f58712f47260711607098 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 8 Apr 2019 03:48:30 +0900 +Subject: [PATCH] fileio: introduce warn_file_is_world_accessible() + +(cherry picked from commit fc0895034d4811e8c6b263c0d902b31535613d76) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 25 +++++++++++++++++++++++++ + src/basic/fileio.h | 3 +++ + 2 files changed, 28 insertions(+) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index cf7c92ebc7..2e74aac554 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -1797,3 +1797,28 @@ int read_line(FILE *f, size_t limit, char **ret) { + + return (int) count; + } ++ ++int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line) { ++ struct stat _st; ++ ++ if (!filename) ++ return 0; ++ ++ if (!st) { ++ if (stat(filename, &_st) < 0) ++ return -errno; ++ st = &_st; ++ } ++ ++ if ((st->st_mode & S_IRWXO) == 0) ++ return 0; ++ ++ if (unit) ++ log_syntax(unit, LOG_WARNING, filename, line, 0, ++ "%s has %04o mode that is too permissive, please adjust the access mode.", ++ filename, st->st_mode & 07777); ++ else ++ log_warning("%s has %04o mode that is too permissive, please adjust the access mode.", ++ filename, st->st_mode & 07777); ++ return 0; ++} +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 06649ef7e6..2c9ce4355b 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + #include "macro.h" +@@ -105,3 +106,5 @@ int read_nul_string(FILE *f, char **ret); + int mkdtemp_malloc(const char *template, char **ret); + + int read_line(FILE *f, size_t limit, char **ret); ++ ++int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line); +-- +2.39.1 + diff --git a/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch b/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch new file mode 100644 index 0000000..af813a5 --- /dev/null +++ b/10018-fileio-read_full_file_full-also-warns-when-file-is-.patch @@ -0,0 +1,64 @@ +From 0dbf69ccdfa7b1f99935c3932445fbfa16dbbe75 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 8 Apr 2019 14:15:10 +0900 +Subject: [PATCH] fileio: read_full_file_full() also warns when file is world + readable and secure flag is set + +(cherry picked from commit 65dcd394d8223bc6bc194f3fe5bd70fed9d9a4fe) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 6 +++++- + src/basic/fileio.h | 4 ++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 2e74aac554..3abeb0d7f4 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -386,6 +386,7 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re + + int read_full_stream_full( + FILE *f, ++ const char *filename, + ReadFullFileFlags flags, + char **ret_contents, + size_t *ret_size) { +@@ -418,6 +419,9 @@ int read_full_stream_full( + * makes us notice the EOF. */ + if (st.st_size > 0) + n_next = st.st_size + 1; ++ ++ if (flags & READ_FULL_FILE_SECURE) ++ (void) warn_file_is_world_accessible(filename, &st, NULL, 0); + } + } + +@@ -508,7 +512,7 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + +- return read_full_stream_full(f, flags, contents, size); ++ return read_full_stream_full(f, filename, flags, contents, size); + } + + static int parse_env_file_internal( +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 2c9ce4355b..3e572dc0de 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -45,9 +45,9 @@ int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **co + static inline int read_full_file(const char *filename, char **contents, size_t *size) { + return read_full_file_full(filename, 0, contents, size); + } +-int read_full_stream_full(FILE *f, ReadFullFileFlags flags, char **contents, size_t *size); ++int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); + static inline int read_full_stream(FILE *f, char **contents, size_t *size) { +- return read_full_stream_full(f, 0, contents, size); ++ return read_full_stream_full(f, NULL, 0, contents, size); + } + int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); + +-- +2.39.1 + diff --git a/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch b/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch new file mode 100644 index 0000000..e434089 --- /dev/null +++ b/10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch @@ -0,0 +1,30 @@ +From 14e0760c251fd5fc51731f7b58079c73f5055d64 Mon Sep 17 00:00:00 2001 +From: Benjamin Robin +Date: Sun, 14 Apr 2019 17:21:27 +0200 +Subject: [PATCH] basic/fileio: Fix memory leak if READ_FULL_FILE_SECURE flag + is used + +The memory leak introduced in #12223 (15f8f02) + +(cherry picked from commit 315a51982af2d480de9f7539346f30425e37a01e) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 3abeb0d7f4..bb804e3afa 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -438,6 +438,7 @@ int read_full_stream_full( + } + memcpy_safe(t, buf, n); + explicit_bzero_safe(buf, n); ++ buf = mfree(buf); + } else { + t = realloc(buf, n_next + 1); + if (!t) +-- +2.39.1 + diff --git a/10020-fileio-add-explicit-flag-for-generating-world-execu.patch b/10020-fileio-add-explicit-flag-for-generating-world-execu.patch new file mode 100644 index 0000000..1a93b5a --- /dev/null +++ b/10020-fileio-add-explicit-flag-for-generating-world-execu.patch @@ -0,0 +1,44 @@ +From 1e0dcd6fa1abea9c561f46556f7f7561b2a46e62 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 17 Jul 2020 11:53:22 +0200 +Subject: [PATCH] fileio: add explicit flag for generating world executable + warning when reading file + +(cherry picked from commit 684aa979f1c4ce5f75ccdc131f32fc0434999918) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 2 +- + src/basic/fileio.h | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index bb804e3afa..833c55b030 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -420,7 +420,7 @@ int read_full_stream_full( + if (st.st_size > 0) + n_next = st.st_size + 1; + +- if (flags & READ_FULL_FILE_SECURE) ++ if (flags & READ_FULL_FILE_WARN_WORLD_READABLE) + (void) warn_file_is_world_accessible(filename, &st, NULL, 0); + } + } +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 3e572dc0de..be10ac77b6 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -26,7 +26,8 @@ typedef enum { + } WriteStringFileFlags; + + typedef enum { +- READ_FULL_FILE_SECURE = 1 << 0, ++ READ_FULL_FILE_SECURE = 1 << 0, ++ READ_FULL_FILE_WARN_WORLD_READABLE = 1 << 3, + } ReadFullFileFlags; + + int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); +-- +2.39.1 + diff --git a/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch b/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch new file mode 100644 index 0000000..f6dc153 --- /dev/null +++ b/10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch @@ -0,0 +1,142 @@ +From 3f4ca11498028756ebde239ae469c0f88e5d3ecc Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 8 Jan 2019 18:29:36 +0100 +Subject: [PATCH] fileio: add 'dir_fd' parameter to read_full_file_full() + +Let's introduce an "at" version of read_full_file(). + +(cherry picked from commit f6be4db4530b7cfea191227c141343a4fb10d4c6) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 84 +++++++++++++++++++++++++++++++++++++++++++--- + src/basic/fileio.h | 5 +-- + 2 files changed, 83 insertions(+), 6 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 833c55b030..d7da834a74 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -501,15 +501,91 @@ finalize: + return r; + } + +-int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { ++static int mode_to_flags(const char *mode) { ++ const char *p; ++ int flags; ++ ++ if ((p = startswith(mode, "r+"))) ++ flags = O_RDWR; ++ else if ((p = startswith(mode, "r"))) ++ flags = O_RDONLY; ++ else if ((p = startswith(mode, "w+"))) ++ flags = O_RDWR|O_CREAT|O_TRUNC; ++ else if ((p = startswith(mode, "w"))) ++ flags = O_WRONLY|O_CREAT|O_TRUNC; ++ else if ((p = startswith(mode, "a+"))) ++ flags = O_RDWR|O_CREAT|O_APPEND; ++ else if ((p = startswith(mode, "a"))) ++ flags = O_WRONLY|O_CREAT|O_APPEND; ++ else ++ return -EINVAL; ++ ++ for (; *p != 0; p++) { ++ ++ switch (*p) { ++ ++ case 'e': ++ flags |= O_CLOEXEC; ++ break; ++ ++ case 'x': ++ flags |= O_EXCL; ++ break; ++ ++ case 'm': ++ /* ignore this here, fdopen() might care later though */ ++ break; ++ ++ case 'c': /* not sure what to do about this one */ ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return flags; ++} ++ ++static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **ret) { ++ FILE *f; ++ ++ /* A combination of fopen() with openat() */ ++ ++ if (dir_fd == AT_FDCWD && flags == 0) { ++ f = fopen(path, mode); ++ if (!f) ++ return -errno; ++ } else { ++ int fd, mode_flags; ++ ++ mode_flags = mode_to_flags(mode); ++ if (mode_flags < 0) ++ return mode_flags; ++ ++ fd = openat(dir_fd, path, mode_flags | flags); ++ if (fd < 0) ++ return -errno; ++ ++ f = fdopen(fd, mode); ++ if (!f) { ++ safe_close(fd); ++ return -errno; ++ } ++ } ++ ++ *ret = f; ++ return 0; ++} ++ ++int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; ++ int r; + + assert(filename); + assert(contents); + +- f = fopen(filename, "re"); +- if (!f) +- return -errno; ++ r = xfopenat(dir_fd, filename, "re", 0, &f); ++ if (r < 0) ++ return r; + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index be10ac77b6..916ddc5e47 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include "macro.h" +@@ -42,9 +43,9 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin + int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); + + int read_one_line_file(const char *filename, char **line); +-int read_full_file_full(const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); ++int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); + static inline int read_full_file(const char *filename, char **contents, size_t *size) { +- return read_full_file_full(filename, 0, contents, size); ++ return read_full_file_full(AT_FDCWD, filename, 0, contents, size); + } + int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); + static inline int read_full_stream(FILE *f, char **contents, size_t *size) { +-- +2.39.1 + diff --git a/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch b/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch new file mode 100644 index 0000000..bb392bc --- /dev/null +++ b/10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch @@ -0,0 +1,271 @@ +From 054669a4cc4897792b6c209fd55ab1fc1d7b9bd5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 17 Jul 2020 12:26:01 +0200 +Subject: [PATCH] fileio: add support for read_full_file() on AF_UNIX stream + sockets + +Optionally, teach read_full_file() the ability to connect to an AF_UNIX +socket if the specified path points to one. + +(cherry picked from commit 412b888ec803cdf96fb1d005bb245d20abdb8f2e) + +[Guorui Yu: Adds sockaddr_un_set_path function to socket-util.{c,h}] +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 62 +++++++++++++++++++++++++++++++++++------ + src/basic/fileio.h | 1 + + src/basic/socket-util.c | 42 ++++++++++++++++++++++++++++ + src/basic/socket-util.h | 1 + + src/test/test-fileio.c | 50 +++++++++++++++++++++++++++++++++ + 5 files changed, 147 insertions(+), 9 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index d7da834a74..9cb0a2bd28 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -27,6 +27,7 @@ + #include "missing.h" + #include "parse-util.h" + #include "path-util.h" ++#include "socket-util.h" + #include "process-util.h" + #include "random-util.h" + #include "stdio-util.h" +@@ -450,21 +451,18 @@ int read_full_stream_full( + + errno = 0; + k = fread(buf + l, 1, n - l, f); +- if (k > 0) +- l += k; ++ ++ assert(k <= n - l); ++ l += k; + + if (ferror(f)) { + r = errno > 0 ? -errno : -EIO; + goto finalize; + } +- + if (feof(f)) + break; + +- /* We aren't expecting fread() to return a short read outside +- * of (error && eof), assert buffer is full and enlarge buffer. +- */ +- assert(l == n); ++ assert(k > 0); /* we can't have read zero bytes because that would have been EOF */ + + /* Safety check */ + if (n >= READ_FULL_BYTES_MAX) { +@@ -584,8 +582,54 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag + assert(contents); + + r = xfopenat(dir_fd, filename, "re", 0, &f); +- if (r < 0) +- return r; ++ if (r < 0) { ++ _cleanup_close_ int dfd = -1, sk = -1; ++ union sockaddr_union sa; ++ ++ /* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */ ++ if (r != -ENXIO) ++ return r; ++ ++ /* If this is enabled, let's try to connect to it */ ++ if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET)) ++ return -ENXIO; ++ ++ if (dir_fd == AT_FDCWD) ++ r = sockaddr_un_set_path(&sa.un, filename); ++ else { ++ char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; ++ ++ /* If we shall operate relative to some directory, then let's use O_PATH first to ++ * open the socket inode, and then connect to it via /proc/self/fd/. We have to do ++ * this since there's not connectat() that takes a directory fd as first arg. */ ++ ++ dfd = openat(dir_fd, filename, O_PATH|O_CLOEXEC); ++ if (dfd < 0) ++ return -errno; ++ ++ xsprintf(procfs_path, "/proc/self/fd/%i", dfd); ++ r = sockaddr_un_set_path(&sa.un, procfs_path); ++ } ++ if (r < 0) ++ return r; ++ ++ sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); ++ if (sk < 0) ++ return -errno; ++ ++ if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) ++ return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is ++ * not a socket after all */ ++ ++ if (shutdown(sk, SHUT_WR) < 0) ++ return -errno; ++ ++ f = fdopen(sk, "r"); ++ if (!f) ++ return -errno; ++ ++ TAKE_FD(sk); ++ } + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 916ddc5e47..1a16e0fd13 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -29,6 +29,7 @@ typedef enum { + typedef enum { + READ_FULL_FILE_SECURE = 1 << 0, + READ_FULL_FILE_WARN_WORLD_READABLE = 1 << 3, ++ READ_FULL_FILE_CONNECT_SOCKET = 1 << 4, + } ReadFullFileFlags; + + int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts); +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index 7f8066123b..427c8b89bb 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -1253,6 +1253,48 @@ int socket_ioctl_fd(void) { + return fd; + } + ++int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path) { ++ size_t l; ++ ++ assert(ret); ++ assert(path); ++ ++ /* Initialize ret->sun_path from the specified argument. This will interpret paths starting with '@' as ++ * abstract namespace sockets, and those starting with '/' as regular filesystem sockets. It won't accept ++ * anything else (i.e. no relative paths), to avoid ambiguities. Note that this function cannot be used to ++ * reference paths in the abstract namespace that include NUL bytes in the name. */ ++ ++ l = strlen(path); ++ if (l < 2) ++ return -EINVAL; ++ if (!IN_SET(path[0], '/', '@')) ++ return -EINVAL; ++ ++ /* Don't allow paths larger than the space in sockaddr_un. Note that we are a tiny bit more restrictive than ++ * the kernel is: we insist on NUL termination (both for abstract namespace and regular file system socket ++ * addresses!), which the kernel doesn't. We do this to reduce chance of incompatibility with other apps that ++ * do not expect non-NUL terminated file system path*/ ++ if (l+1 > sizeof(ret->sun_path)) ++ return -EINVAL; ++ ++ *ret = (struct sockaddr_un) { ++ .sun_family = AF_UNIX, ++ }; ++ ++ if (path[0] == '@') { ++ /* Abstract namespace socket */ ++ memcpy(ret->sun_path + 1, path + 1, l); /* copy *with* trailing NUL byte */ ++ return (int) (offsetof(struct sockaddr_un, sun_path) + l); /* 🔥 *don't* 🔥 include trailing NUL in size */ ++ ++ } else { ++ assert(path[0] == '/'); ++ ++ /* File system socket */ ++ memcpy(ret->sun_path, path, l + 1); /* copy *with* trailing NUL byte */ ++ return (int) (offsetof(struct sockaddr_un, sun_path) + l + 1); /* include trailing NUL in size */ ++ } ++} ++ + int socket_pass_pktinfo(int fd, bool b) { + int af; + socklen_t sl = sizeof(af); +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 30baba6c03..36edc58caf 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -186,6 +186,7 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng + }) + + int socket_ioctl_fd(void); ++int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path); + + static inline int setsockopt_int(int fd, int level, int optname, int value) { + if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0) +diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c +index 14ba075144..82b7cb1242 100644 +--- a/src/test/test-fileio.c ++++ b/src/test/test-fileio.c +@@ -14,6 +14,8 @@ + #include "io-util.h" + #include "parse-util.h" + #include "process-util.h" ++#include "rm-rf.h" ++#include "socket-util.h" + #include "string-util.h" + #include "strv.h" + #include "util.h" +@@ -709,6 +711,53 @@ static void test_read_line3(void) { + assert_se(read_line(f, LINE_MAX, NULL) == 0); + } + ++static void test_read_full_file_socket(void) { ++ _cleanup_(rm_rf_physical_and_freep) char *z = NULL; ++ _cleanup_close_ int listener = -1; ++ _cleanup_free_ char *data = NULL; ++ union sockaddr_union sa; ++ const char *j; ++ size_t size; ++ pid_t pid; ++ int r; ++ ++ log_info("/* %s */", __func__); ++ ++ listener = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); ++ assert_se(listener >= 0); ++ ++ assert_se(mkdtemp_malloc(NULL, &z) >= 0); ++ j = strjoina(z, "/socket"); ++ ++ assert_se(sockaddr_un_set_path(&sa.un, j) >= 0); ++ ++ assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0); ++ assert_se(listen(listener, 1) >= 0); ++ ++ r = safe_fork("(server)", FORK_DEATHSIG|FORK_LOG, &pid); ++ assert_se(r >= 0); ++ if (r == 0) { ++ _cleanup_close_ int rfd = -1; ++ /* child */ ++ ++ rfd = accept4(listener, NULL, 0, SOCK_CLOEXEC); ++ assert_se(rfd >= 0); ++ ++#define TEST_STR "This is a test\nreally." ++ ++ assert_se(write(rfd, TEST_STR, strlen(TEST_STR)) == strlen(TEST_STR)); ++ _exit(EXIT_SUCCESS); ++ } ++ ++ assert_se(read_full_file_full(AT_FDCWD, j, 0, &data, &size) == -ENXIO); ++ assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, &data, &size) >= 0); ++ assert_se(size == strlen(TEST_STR)); ++ assert_se(streq(data, TEST_STR)); ++ ++ assert_se(wait_for_terminate_and_check("(server)", pid, WAIT_LOG) >= 0); ++#undef TEST_STR ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); +@@ -733,6 +782,7 @@ int main(int argc, char *argv[]) { + test_read_line(); + test_read_line2(); + test_read_line3(); ++ test_read_full_file_socket(); + + return 0; + } +-- +2.39.1 + diff --git a/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch b/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch new file mode 100644 index 0000000..2edc538 --- /dev/null +++ b/10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch @@ -0,0 +1,181 @@ +From 0717de25e6508b10ea034fa1b96675f18100ac01 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Nov 2020 12:07:51 +0100 +Subject: [PATCH] fileio: beef up READ_FULL_FILE_CONNECT_SOCKET to allow + setting sender socket name + +This beefs up the READ_FULL_FILE_CONNECT_SOCKET logic of +read_full_file_full() a bit: when used a sender socket name may be +specified. If specified as NULL behaviour is as before: the client +socket name is picked by the kernel. But if specified as non-NULL the +client can pick a socket name to use when connecting. This is useful to +communicate a minimal amount of metainformation from client to server, +outside of the transport payload. + +Specifically, these beefs up the service credential logic to pass an +abstract AF_UNIX socket name as client socket name when connecting via +READ_FULL_FILE_CONNECT_SOCKET, that includes the requesting unit name +and the eventual credential name. This allows servers implementing the +trivial credential socket logic to distinguish clients: via a simple +getpeername() it can be determined which unit is requesting a +credential, and which credential specifically. + +Example: with this patch in place, in a unit file "waldo.service" a +configuration line like the following: + + LoadCredential=foo:/run/quux/creds.sock + +will result in a connection to the AF_UNIX socket /run/quux/creds.sock, +originating from an abstract namespace AF_UNIX socket: + + @$RANDOM/unit/waldo.service/foo + +(The $RANDOM is replaced by some randomized string. This is included in +the socket name order to avoid namespace squatting issues: the abstract +socket namespace is open to unprivileged users after all, and care needs +to be taken not to use guessable names) + +The services listening on the /run/quux/creds.sock socket may thus +easily retrieve the name of the unit the credential is requested for +plus the credential name, via a simpler getpeername(), discarding the +random preifx and the /unit/ string. + +This logic uses "/" as separator between the fields, since both unit +names and credential names appear in the file system, and thus are +designed to use "/" as outer separators. Given that it's a good safe +choice to use as separators here, too avoid any conflicts. + +This is a minimal patch only: the new logic is used only for the unit +file credential logic. For other places where we use +READ_FULL_FILE_CONNECT_SOCKET it is probably a good idea to use this +scheme too, but this should be done carefully in later patches, since +the socket names become API that way, and we should determine the right +amount of info to pass over. + +(cherry picked from commit 142e9756c98c69cdd5d03df4028700acb5739f72) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 22 +++++++++++++++++++++- + src/basic/fileio.h | 4 ++-- + src/test/test-fileio.c | 19 ++++++++++++++++--- + 3 files changed, 39 insertions(+), 6 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 9cb0a2bd28..35eaa3c1c7 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -574,7 +574,13 @@ static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, F + return 0; + } + +-int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size) { ++int read_full_file_full( ++ int dir_fd, ++ const char *filename, ++ ReadFullFileFlags flags, ++ const char *bind_name, ++ char **contents, size_t *size) { ++ + _cleanup_fclose_ FILE *f = NULL; + int r; + +@@ -617,6 +623,20 @@ int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flag + if (sk < 0) + return -errno; + ++ if (bind_name) { ++ /* If the caller specified a socket name to bind to, do so before connecting. This is ++ * useful to communicate some minor, short meta-information token from the client to ++ * the server. */ ++ union sockaddr_union bsa; ++ ++ r = sockaddr_un_set_path(&bsa.un, bind_name); ++ if (r < 0) ++ return r; ++ ++ if (bind(sk, &bsa.sa, r) < 0) ++ return r; ++ } ++ + if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) + return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is + * not a socket after all */ +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 1a16e0fd13..82897e209c 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -44,9 +44,9 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin + int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); + + int read_one_line_file(const char *filename, char **line); +-int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); ++int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, const char *bind_name, char **contents, size_t *size); + static inline int read_full_file(const char *filename, char **contents, size_t *size) { +- return read_full_file_full(AT_FDCWD, filename, 0, contents, size); ++ return read_full_file_full(AT_FDCWD, filename, 0, NULL, contents, size); + } + int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); + static inline int read_full_stream(FILE *f, char **contents, size_t *size) { +diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c +index 82b7cb1242..5ec70eec14 100644 +--- a/src/test/test-fileio.c ++++ b/src/test/test-fileio.c +@@ -14,6 +14,7 @@ + #include "io-util.h" + #include "parse-util.h" + #include "process-util.h" ++#include "random-util.h" + #include "rm-rf.h" + #include "socket-util.h" + #include "string-util.h" +@@ -714,7 +715,7 @@ static void test_read_line3(void) { + static void test_read_full_file_socket(void) { + _cleanup_(rm_rf_physical_and_freep) char *z = NULL; + _cleanup_close_ int listener = -1; +- _cleanup_free_ char *data = NULL; ++ _cleanup_free_ char *data = NULL, *clientname = NULL; + union sockaddr_union sa; + const char *j; + size_t size; +@@ -734,23 +735,35 @@ static void test_read_full_file_socket(void) { + assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0); + assert_se(listen(listener, 1) >= 0); + ++ /* Bind the *client* socket to some randomized name, to verify that this works correctly. */ ++ assert_se(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()) >= 0); ++ + r = safe_fork("(server)", FORK_DEATHSIG|FORK_LOG, &pid); + assert_se(r >= 0); + if (r == 0) { ++ union sockaddr_union peer = {}; ++ socklen_t peerlen = sizeof(peer); + _cleanup_close_ int rfd = -1; + /* child */ + + rfd = accept4(listener, NULL, 0, SOCK_CLOEXEC); + assert_se(rfd >= 0); + ++ assert_se(getpeername(rfd, &peer.sa, &peerlen) >= 0); ++ ++ assert_se(peer.un.sun_family == AF_UNIX); ++ assert_se(peerlen > offsetof(struct sockaddr_un, sun_path)); ++ assert_se(peer.un.sun_path[0] == 0); ++ assert_se(streq(peer.un.sun_path + 1, clientname + 1)); ++ + #define TEST_STR "This is a test\nreally." + + assert_se(write(rfd, TEST_STR, strlen(TEST_STR)) == strlen(TEST_STR)); + _exit(EXIT_SUCCESS); + } + +- assert_se(read_full_file_full(AT_FDCWD, j, 0, &data, &size) == -ENXIO); +- assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, &data, &size) >= 0); ++ assert_se(read_full_file_full(AT_FDCWD, j, 0, NULL, &data, &size) == -ENXIO); ++ assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); + assert_se(size == strlen(TEST_STR)); + assert_se(streq(data, TEST_STR)); + +-- +2.39.1 + diff --git a/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch b/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch new file mode 100644 index 0000000..08e8f40 --- /dev/null +++ b/10024-fileio-teach-read_full_file_full-to-read-from-offse.patch @@ -0,0 +1,246 @@ +From 5be0e8a2c3e683c195fd872979d6e5741c80d13f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 4 Nov 2020 20:25:06 +0100 +Subject: [PATCH] fileio: teach read_full_file_full() to read from offset/with + maximum size + +(cherry picked from commit 7399b3f8083b65db4cb9acb17e4b5c897ba7946d) + +Signed-off-by: Guorui Yu +--- + src/basic/fileio.c | 60 ++++++++++++++++++++++++++++++------------ + src/basic/fileio.h | 12 ++++----- + src/test/test-fileio.c | 49 ++++++++++++++++++++++++++++++++-- + 3 files changed, 96 insertions(+), 25 deletions(-) + +diff --git a/src/basic/fileio.c b/src/basic/fileio.c +index 35eaa3c1c7..c14f9797bd 100644 +--- a/src/basic/fileio.c ++++ b/src/basic/fileio.c +@@ -388,44 +388,58 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re + int read_full_stream_full( + FILE *f, + const char *filename, ++ uint64_t offset, ++ size_t size, + ReadFullFileFlags flags, + char **ret_contents, + size_t *ret_size) { + + _cleanup_free_ char *buf = NULL; +- struct stat st; + size_t n, n_next, l; + int fd, r; + + assert(f); + assert(ret_contents); + +- n_next = LINE_MAX; /* Start size */ ++ if (offset != UINT64_MAX && offset > LONG_MAX) ++ return -ERANGE; ++ ++ n_next = size != SIZE_MAX ? size : LINE_MAX; /* Start size */ + + fd = fileno(f); +- if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's +- * optimize our buffering) */ ++ if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see ++ * fmemopen()), let's optimize our buffering */ ++ struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + if (S_ISREG(st.st_mode)) { +- +- /* Safety check */ +- if (st.st_size > READ_FULL_BYTES_MAX) +- return -E2BIG; +- +- /* Start with the right file size. Note that we increase the size +- * to read here by one, so that the first read attempt already +- * makes us notice the EOF. */ +- if (st.st_size > 0) +- n_next = st.st_size + 1; ++ if (size == SIZE_MAX) { ++ uint64_t rsize = ++ LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset); ++ ++ /* Safety check */ ++ if (rsize > READ_FULL_BYTES_MAX) ++ return -E2BIG; ++ ++ /* Start with the right file size. Note that we increase the size to read ++ * here by one, so that the first read attempt already makes us notice the ++ * EOF. If the reported size of the file is zero, we avoid this logic ++ * however, since quite likely it might be a virtual file in procfs that all ++ * report a zero file size. */ ++ if (st.st_size > 0) ++ n_next = rsize + 1; ++ } + + if (flags & READ_FULL_FILE_WARN_WORLD_READABLE) + (void) warn_file_is_world_accessible(filename, &st, NULL, 0); + } + } + ++ if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0) ++ return -errno; ++ + n = l = 0; + for (;;) { + char *t; +@@ -462,6 +476,11 @@ int read_full_stream_full( + if (feof(f)) + break; + ++ if (size != SIZE_MAX) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */ ++ assert(l == size); ++ break; ++ } ++ + assert(k > 0); /* we can't have read zero bytes because that would have been EOF */ + + /* Safety check */ +@@ -577,15 +596,18 @@ static int xfopenat(int dir_fd, const char *path, const char *mode, int flags, F + int read_full_file_full( + int dir_fd, + const char *filename, ++ uint64_t offset, ++ size_t size, + ReadFullFileFlags flags, + const char *bind_name, +- char **contents, size_t *size) { ++ char **ret_contents, ++ size_t *ret_size) { + + _cleanup_fclose_ FILE *f = NULL; + int r; + + assert(filename); +- assert(contents); ++ assert(ret_contents); + + r = xfopenat(dir_fd, filename, "re", 0, &f); + if (r < 0) { +@@ -600,6 +622,10 @@ int read_full_file_full( + if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET)) + return -ENXIO; + ++ /* Seeking is not supported on AF_UNIX sockets */ ++ if (offset != UINT64_MAX) ++ return -ESPIPE; ++ + if (dir_fd == AT_FDCWD) + r = sockaddr_un_set_path(&sa.un, filename); + else { +@@ -653,7 +679,7 @@ int read_full_file_full( + + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + +- return read_full_stream_full(f, filename, flags, contents, size); ++ return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size); + } + + static int parse_env_file_internal( +diff --git a/src/basic/fileio.h b/src/basic/fileio.h +index 82897e209c..03150ce776 100644 +--- a/src/basic/fileio.h ++++ b/src/basic/fileio.h +@@ -44,13 +44,13 @@ static inline int write_string_file(const char *fn, const char *line, WriteStrin + int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); + + int read_one_line_file(const char *filename, char **line); +-int read_full_file_full(int dir_fd, const char *filename, ReadFullFileFlags flags, const char *bind_name, char **contents, size_t *size); +-static inline int read_full_file(const char *filename, char **contents, size_t *size) { +- return read_full_file_full(AT_FDCWD, filename, 0, NULL, contents, size); ++int read_full_file_full(int dir_fd, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, const char *bind_name, char **ret_contents, size_t *ret_size); ++static inline int read_full_file(const char *filename, char **ret_contents, size_t *ret_size) { ++ return read_full_file_full(AT_FDCWD, filename, UINT64_MAX, SIZE_MAX, 0, NULL, ret_contents, ret_size); + } +-int read_full_stream_full(FILE *f, const char *filename, ReadFullFileFlags flags, char **contents, size_t *size); +-static inline int read_full_stream(FILE *f, char **contents, size_t *size) { +- return read_full_stream_full(f, NULL, 0, contents, size); ++int read_full_stream_full(FILE *f, const char *filename, uint64_t offset, size_t size, ReadFullFileFlags flags, char **ret_contents, size_t *ret_size); ++static inline int read_full_stream(FILE *f, char **ret_contents, size_t *ret_size) { ++ return read_full_stream_full(f, NULL, UINT64_MAX, SIZE_MAX, 0, ret_contents, ret_size); + } + int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size); + +diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c +index 5ec70eec14..5d0006149b 100644 +--- a/src/test/test-fileio.c ++++ b/src/test/test-fileio.c +@@ -762,8 +762,8 @@ static void test_read_full_file_socket(void) { + _exit(EXIT_SUCCESS); + } + +- assert_se(read_full_file_full(AT_FDCWD, j, 0, NULL, &data, &size) == -ENXIO); +- assert_se(read_full_file_full(AT_FDCWD, j, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); ++ assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, 0, NULL, &data, &size) == -ENXIO); ++ assert_se(read_full_file_full(AT_FDCWD, j, UINT64_MAX, SIZE_MAX, READ_FULL_FILE_CONNECT_SOCKET, clientname, &data, &size) >= 0); + assert_se(size == strlen(TEST_STR)); + assert_se(streq(data, TEST_STR)); + +@@ -771,6 +771,50 @@ static void test_read_full_file_socket(void) { + #undef TEST_STR + } + ++static void test_read_full_file_offset_size(void) { ++ _cleanup_fclose_ FILE *f = NULL; ++ _cleanup_(unlink_and_freep) char *fn = NULL; ++ _cleanup_free_ char *rbuf = NULL; ++ size_t rbuf_size; ++ uint8_t buf[4711]; ++ ++ random_bytes(buf, sizeof(buf)); ++ ++ assert_se(tempfn_random_child(NULL, NULL, &fn) >= 0); ++ assert_se(f = fopen(fn, "we")); ++ assert_se(fwrite(buf, 1, sizeof(buf), f) == sizeof(buf)); ++ assert_se(fflush_and_check(f) >= 0); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, SIZE_MAX, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == sizeof(buf)); ++ assert_se(memcmp(buf, rbuf, rbuf_size) == 0); ++ rbuf = mfree(rbuf); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, UINT64_MAX, 128, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == 128); ++ assert_se(memcmp(buf, rbuf, rbuf_size) == 0); ++ rbuf = mfree(rbuf); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, 1234, SIZE_MAX, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == sizeof(buf) - 1234); ++ assert_se(memcmp(buf + 1234, rbuf, rbuf_size) == 0); ++ rbuf = mfree(rbuf); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, 2345, 777, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == 777); ++ assert_se(memcmp(buf + 2345, rbuf, rbuf_size) == 0); ++ rbuf = mfree(rbuf); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, 4700, 20, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == 11); ++ assert_se(memcmp(buf + 4700, rbuf, rbuf_size) == 0); ++ rbuf = mfree(rbuf); ++ ++ assert_se(read_full_file_full(AT_FDCWD, fn, 10000, 99, 0, NULL, &rbuf, &rbuf_size) >= 0); ++ assert_se(rbuf_size == 0); ++ rbuf = mfree(rbuf); ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); +@@ -796,6 +840,7 @@ int main(int argc, char *argv[]) { + test_read_line2(); + test_read_line3(); + test_read_full_file_socket(); ++ test_read_full_file_offset_size(); + + return 0; + } +-- +2.39.1 + diff --git a/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch b/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch new file mode 100644 index 0000000..bb66170 --- /dev/null +++ b/10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch @@ -0,0 +1,95 @@ +From 8ef03861b75cf0a70511760c395cb4bd228c37b9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 4 Nov 2020 17:24:53 +0100 +Subject: [PATCH] cryptsetup: port cryptsetup's main key file logic over to + read_full_file_full() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously, we'd load the file with libcryptsetup's calls. Let's do that +in our own, so that we can make use of READ_FULL_FILE_CONNECT_SOCKET, +i.e. read in keys via AF_UNIX sockets, so that people can plug key +providers into our logic. + +This provides functionality similar to Debian's keyscript= crypttab +option (see → #3007), as it allows key scripts to be run as socket +activated services, that have stdout connected to the activated socket. +In contrast to traditional keyscript= support this logic runs stuff out +of process however, which is beneficial, since it allows sandboxing and +similar. + +(cherry picked from commit 165a476841ff1aa3aab3508771db9495ab073c7a) + +Signed-off-by: Guorui Yu +--- + src/cryptsetup/cryptsetup.c | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c +index 11162eb722..9251e0eba8 100644 +--- a/src/cryptsetup/cryptsetup.c ++++ b/src/cryptsetup/cryptsetup.c +@@ -17,6 +17,7 @@ + #include "mount-util.h" + #include "parse-util.h" + #include "path-util.h" ++#include "random-util.h" + #include "string-util.h" + #include "strv.h" + #include "util.h" +@@ -480,6 +481,15 @@ static int attach_tcrypt( + return 0; + } + ++static char *make_bindname(const char *volume) { ++ char *s; ++ ++ if (asprintf(&s, "@%" PRIx64"/cryptsetup/%s", random_u64(), volume) < 0) ++ return NULL; ++ ++ return s; ++} ++ + static int attach_luks_or_plain(struct crypt_device *cd, + const char *name, + const char *key_file, +@@ -553,13 +563,30 @@ static int attach_luks_or_plain(struct crypt_device *cd, + crypt_get_device_name(cd)); + + if (key_file) { +- r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags); +- if (r == -EPERM) { +- log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); ++ _cleanup_(erase_and_freep) char *kfdata = NULL; ++ _cleanup_free_ char *bindname = NULL; ++ size_t kfsize; ++ ++ /* If we read the key via AF_UNIX, make this client recognizable */ ++ bindname = make_bindname(name); ++ if (!bindname) ++ return log_oom(); ++ ++ r = read_full_file_full( ++ AT_FDCWD, key_file, ++ arg_keyfile_offset == 0 ? UINT64_MAX : arg_keyfile_offset, ++ arg_keyfile_size == 0 ? SIZE_MAX : arg_keyfile_size, ++ READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET, ++ bindname, ++ &kfdata, &kfsize); ++ if (r == -ENOENT) { ++ log_error_errno(r, "Failed to activate, key file '%s' missing.", key_file); + return -EAGAIN; /* Log actual error, but return EAGAIN */ + } +- if (r == -EINVAL) { +- log_error_errno(r, "Failed to activate with key file '%s'. (Key file missing?)", key_file); ++ ++ r = crypt_activate_by_passphrase(cd, name, arg_key_slot, kfdata, kfsize, flags); ++ if (r == -EPERM) { ++ log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file); + return -EAGAIN; /* Log actual error, but return EAGAIN */ + } + if (r < 0) +-- +2.39.1 + diff --git a/systemd.spec b/systemd.spec index 05cd3aa..465fe17 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1044,6 +1044,19 @@ Patch10009: 10009-systemd-anolis-support-loongarch64.patch Patch10010: 10010-test-catalog-Fix-coredump-when-compiled-under-GCC10.patch Patch10011: 10011-hwdb-add-Iluvatar-CoreX.patch Patch10012: 10012-seccomp-add-loongarch-support.patch +Patch10013: 10013-fileio-when-reading-a-full-file-into-memory-refuse-.patch +Patch10014: 10014-util-introduce-explicit_bzero_safe-for-explicit-mem.patch +Patch10015: 10015-util-introduce-erase_and_free-helper.patch +Patch10016: 10016-util-introduce-READ_FULL_FILE_SECURE-flag-for-readi.patch +Patch10017: 10017-fileio-introduce-warn_file_is_world_accessible.patch +Patch10018: 10018-fileio-read_full_file_full-also-warns-when-file-is-.patch +Patch10019: 10019-basic-fileio-Fix-memory-leak-if-READ_FULL_FILE_SECU.patch +Patch10020: 10020-fileio-add-explicit-flag-for-generating-world-execu.patch +Patch10021: 10021-fileio-add-dir_fd-parameter-to-read_full_file_full.patch +Patch10022: 10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch +Patch10023: 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch +Patch10024: 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch +Patch10025: 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1690,6 +1703,19 @@ fi - seccomp: add loongarch64 support (Liwei Ge) - seccomp: remove loongarch64 switch(Liwei Ge) - umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed success(yuanhui) +- fileio: when reading a full file into memory, refuse inner NUL bytes (Guorui Yu) +- util: introduce explicit_bzero_safe for explicit memset (Guorui Yu) +- util: introduce erase_and_free() helper (Guorui Yu) +- util: introduce READ_FULL_FILE_SECURE flag for reading secure data (Guorui Yu) +- fileio: introduce warn_file_is_world_accessible() (Guorui Yu) +- fileio: read_full_file_full() also warns when file is world readable and secure flag is set (Guorui Yu) +- basic/fileio: Fix memory leak if READ_FULL_FILE_SECURE flag is used (Guorui Yu) +- fileio: add explicit flag for generating world executable warning when reading file (Guorui Yu) +- fileio: add 'dir_fd' parameter to read_full_file_full() (Guorui Yu) +- fileio: add support for read_full_file() on AF_UNIX stream sockets (Guorui Yu) +- fileio: beef up READ_FULL_FILE_CONNECT_SOCKET to allow setting sender socket name (Guorui Yu) +- fileio: teach read_full_file_full() to read from offset/with maximum size (Guorui Yu) +- cryptsetup: port cryptsetup's main key file logic over to read_full_file_full() (Guorui Yu) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From e6d821ffa7e5c1acd631a9e5fbbbce0813f9c6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=A0=E5=87=8C?= Date: Mon, 30 Oct 2023 15:54:33 +0800 Subject: [PATCH 09/11] Add optimized patches (hwdb,cgroup) - Update upstream parse_hwdb.py to fix parse-hwdb error - cgroup: do not refresh cgroup devices config when daemon-reload - core: introduce cgroup full delegation for compability --- 20001-hwdb-parse_hwdb_dot_py.patch | 299 ++++++++++++++++++ ...fresh-cgroup-devices-config-when-dae.patch | 26 ++ ...group-full-delegation-for-compabilit.patch | 133 ++++++++ systemd.spec | 7 + 4 files changed, 465 insertions(+) create mode 100644 20001-hwdb-parse_hwdb_dot_py.patch create mode 100644 20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch create mode 100644 20003-core-introduce-cgroup-full-delegation-for-compabilit.patch diff --git a/20001-hwdb-parse_hwdb_dot_py.patch b/20001-hwdb-parse_hwdb_dot_py.patch new file mode 100644 index 0000000..71bf1c5 --- /dev/null +++ b/20001-hwdb-parse_hwdb_dot_py.patch @@ -0,0 +1,299 @@ +From: rpm-build +Date: Thu, 28 Apr 2022 01:49:39 +0000 +Subject: [PATCH] Update upstream parse_hwdb.py to fix parse-hwdb error + +This patch does not correspond to a specific commit from upstream. Instead, it +is directly taken from + +https://github.com/systemd/systemd/blob/f2c36c0e2445fa95ba109017d4b768b2fd825c43/hwdb.d/parse_hwdb.py. + +This patch allows systemd-udev to parse newer hwdb. Hwdb is updated mostly +because of new hardware. Therefore, this patch allows systemd-udev to recongnize +these new hardware. + +--- +diff -uNrp systemd-239.orig/hwdb/parse_hwdb.py systemd-239/hwdb/parse_hwdb.py +--- systemd-239.orig/hwdb/parse_hwdb.py 2022-04-28 11:32:08.740731756 +0800 ++++ systemd-239/hwdb/parse_hwdb.py 2022-04-28 11:32:08.741731786 +0800 +@@ -1,6 +1,5 @@ + #!/usr/bin/env python3 +-# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ +-# SPDX-License-Identifier: MIT ++# SPDX-License-Identifier: MIT + # + # This file is distributed under the MIT license, see below. + # +@@ -30,12 +29,11 @@ import sys + import os + + try: +- from pyparsing import (Word, White, Literal, ParserElement, Regex, +- LineStart, LineEnd, ++ from pyparsing import (Word, White, Literal, ParserElement, Regex, LineEnd, + OneOrMore, Combine, Or, Optional, Suppress, Group, + nums, alphanums, printables, +- stringEnd, pythonStyleComment, QuotedString, +- ParseBaseException) ++ stringEnd, pythonStyleComment, ++ ParseBaseException, __diag__) + except ImportError: + print('pyparsing is not available') + sys.exit(77) +@@ -52,33 +50,61 @@ except ImportError: + # don't do caching on old python + lru_cache = lambda: (lambda f: f) + ++__diag__.warn_multiple_tokens_in_named_alternation = True ++__diag__.warn_ungrouped_named_tokens_in_collection = True ++__diag__.warn_name_set_on_empty_Forward = True ++__diag__.warn_on_multiple_string_args_to_oneof = True ++__diag__.enable_debug_on_named_expressions = True ++ + EOL = LineEnd().suppress() + EMPTYLINE = LineEnd() + COMMENTLINE = pythonStyleComment + EOL + INTEGER = Word(nums) +-STRING = QuotedString('"') + REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER)) + SIGNED_REAL = Combine(Optional(Word('-+')) + REAL) + UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_') + ++# Those patterns are used in type-specific matches + TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'), + 'evdev': ('name', 'atkbd', 'input'), ++ 'fb': ('pci'), + 'id-input': ('modalias'), + 'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'), + 'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'), + 'keyboard': ('name', ), + 'sensor': ('modalias', ), ++ 'ieee1394-unit-function' : ('node', ), ++ 'camera': ('usb'), + } + ++# Patterns that are used to set general properties on a device ++GENERAL_MATCHES = {'acpi', ++ 'bluetooth', ++ 'usb', ++ 'pci', ++ 'sdio', ++ 'vmbus', ++ 'OUI', ++ 'ieee1394', ++ } ++ ++def upperhex_word(length): ++ return Word(nums + 'ABCDEF', exact=length) ++ + @lru_cache() + def hwdb_grammar(): + ParserElement.setDefaultWhitespaceChars('') + + prefix = Or(category + ':' + Or(conn) + ':' + for category, conn in TYPES.items()) +- matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL ++ ++ matchline_typed = Combine(prefix + Word(printables + ' ' + '®')) ++ matchline_general = Combine(Or(GENERAL_MATCHES) + ':' + Word(printables + ' ' + '®')) ++ matchline = (matchline_typed | matchline_general) + EOL ++ + propertyline = (White(' ', exact=1).suppress() + +- Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.!-;, "') - Optional(pythonStyleComment)) + ++ Combine(UDEV_TAG - '=' - Optional(Word(alphanums + '_=:@*.!-;, "/')) ++ - Optional(pythonStyleComment)) + + EOL) + propertycomment = White(' ', exact=1) + pythonStyleComment + EOL + +@@ -87,7 +113,7 @@ def hwdb_grammar(): + (EMPTYLINE ^ stringEnd()).suppress()) + commentgroup = OneOrMore(COMMENTLINE).suppress() - EMPTYLINE.suppress() + +- grammar = OneOrMore(group('GROUPS*') ^ commentgroup) + stringEnd() ++ grammar = OneOrMore(Group(group)('GROUPS*') ^ commentgroup) + stringEnd() + + return grammar + +@@ -95,39 +121,57 @@ def hwdb_grammar(): + def property_grammar(): + ParserElement.setDefaultWhitespaceChars(' ') + +- dpi_setting = (Optional('*')('DEFAULT') + INTEGER('DPI') + Suppress('@') + INTEGER('HZ'))('SETTINGS*') ++ dpi_setting = Group(Optional('*')('DEFAULT') + INTEGER('DPI') + Optional(Suppress('@') + INTEGER('HZ')))('SETTINGS*') + mount_matrix_row = SIGNED_REAL + ',' + SIGNED_REAL + ',' + SIGNED_REAL +- mount_matrix = (mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX') ++ mount_matrix = Group(mount_matrix_row + ';' + mount_matrix_row + ';' + mount_matrix_row)('MOUNT_MATRIX') ++ xkb_setting = Optional(Word(alphanums + '+-/@._')) ++ ++ # Although this set doesn't cover all of characters in database entries, it's enough for test targets. ++ name_literal = Word(printables + ' ') + + props = (('MOUSE_DPI', Group(OneOrMore(dpi_setting))), + ('MOUSE_WHEEL_CLICK_ANGLE', INTEGER), + ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', INTEGER), + ('MOUSE_WHEEL_CLICK_COUNT', INTEGER), + ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', INTEGER), +- ('ID_INPUT', Literal('1')), +- ('ID_INPUT_ACCELEROMETER', Literal('1')), +- ('ID_INPUT_JOYSTICK', Literal('1')), +- ('ID_INPUT_KEY', Literal('1')), +- ('ID_INPUT_KEYBOARD', Literal('1')), +- ('ID_INPUT_MOUSE', Literal('1')), +- ('ID_INPUT_POINTINGSTICK', Literal('1')), +- ('ID_INPUT_SWITCH', Literal('1')), +- ('ID_INPUT_TABLET', Literal('1')), +- ('ID_INPUT_TABLET_PAD', Literal('1')), +- ('ID_INPUT_TOUCHPAD', Literal('1')), +- ('ID_INPUT_TOUCHSCREEN', Literal('1')), +- ('ID_INPUT_TRACKBALL', Literal('1')), +- ('MOUSE_WHEEL_TILT_HORIZONTAL', Literal('1')), +- ('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')), ++ ('ID_AUTOSUSPEND', Or((Literal('0'), Literal('1')))), ++ ('ID_AV_PRODUCTION_CONTROLLER', Or((Literal('0'), Literal('1')))), ++ ('ID_PERSIST', Or((Literal('0'), Literal('1')))), ++ ('ID_PDA', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_ACCELEROMETER', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_JOYSTICK', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_KEY', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_KEYBOARD', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_MOUSE', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_POINTINGSTICK', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_SWITCH', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_TABLET', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_TABLET_PAD', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_TOUCHPAD', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_TOUCHSCREEN', Or((Literal('0'), Literal('1')))), ++ ('ID_INPUT_TRACKBALL', Or((Literal('0'), Literal('1')))), ++ ('ID_SIGNAL_ANALYZER', Or((Literal('0'), Literal('1')))), + ('POINTINGSTICK_SENSITIVITY', INTEGER), + ('POINTINGSTICK_CONST_ACCEL', REAL), + ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))), + ('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))), +- ('XKB_FIXED_LAYOUT', STRING), +- ('XKB_FIXED_VARIANT', STRING), ++ ('XKB_FIXED_LAYOUT', xkb_setting), ++ ('XKB_FIXED_VARIANT', xkb_setting), ++ ('XKB_FIXED_MODEL', xkb_setting), + ('KEYBOARD_LED_NUMLOCK', Literal('0')), + ('KEYBOARD_LED_CAPSLOCK', Literal('0')), + ('ACCEL_MOUNT_MATRIX', mount_matrix), ++ ('ACCEL_LOCATION', Or(('display', 'base'))), ++ ('PROXIMITY_NEAR_LEVEL', INTEGER), ++ ('IEEE1394_UNIT_FUNCTION_MIDI', Or((Literal('0'), Literal('1')))), ++ ('IEEE1394_UNIT_FUNCTION_AUDIO', Or((Literal('0'), Literal('1')))), ++ ('IEEE1394_UNIT_FUNCTION_VIDEO', Or((Literal('0'), Literal('1')))), ++ ('ID_VENDOR_FROM_DATABASE', name_literal), ++ ('ID_MODEL_FROM_DATABASE', name_literal), ++ ('ID_TAG_MASTER_OF_SEAT', Literal('1')), ++ ('ID_INFRARED_CAMERA', Or((Literal('0'), Literal('1')))), ++ ('ID_CAMERA_DIRECTION', Or(('front', 'rear'))), + ) + fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') + for name, val in props] +@@ -165,8 +209,29 @@ def parse(fname): + return [] + return [convert_properties(g) for g in parsed.GROUPS] + +-def check_match_uniqueness(groups): ++def check_matches(groups): + matches = sum((group[0] for group in groups), []) ++ ++ # This is a partial check. The other cases could be also done, but those ++ # two are most commonly wrong. ++ grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*', ++ 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*', ++ } ++ ++ for match in matches: ++ prefix, rest = match.split(':', maxsplit=1) ++ gr = grammars.get(prefix) ++ if gr: ++ # we check this first to provide an easy error message ++ if rest[-1] not in '*:': ++ error('pattern {} does not end with "*" or ":"', match) ++ ++ try: ++ gr.parseString(rest) ++ except ParseBaseException as e: ++ error('Pattern {!r} is invalid: {}', rest, e) ++ continue ++ + matches.sort() + prev = None + for match in matches: +@@ -196,15 +261,25 @@ def check_one_mount_matrix(prop, value): + def check_one_keycode(prop, value): + if value != '!' and ecodes is not None: + key = 'KEY_' + value.upper() +- if key not in ecodes: +- key = value.upper() +- if key not in ecodes: +- error('Keycode {} unknown', key) ++ if not (key in ecodes or ++ value.upper() in ecodes or ++ # new keys added in kernel 5.5 ++ 'KBD_LCD_MENU' in key): ++ error('Keycode {} unknown', key) ++ ++def check_wheel_clicks(properties): ++ pairs = (('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', 'MOUSE_WHEEL_CLICK_COUNT'), ++ ('MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL', 'MOUSE_WHEEL_CLICK_ANGLE'), ++ ('MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL', 'MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL'), ++ ('MOUSE_WHEEL_CLICK_COUNT', 'MOUSE_WHEEL_CLICK_ANGLE')) ++ for pair in pairs: ++ if pair[0] in properties and pair[1] not in properties: ++ error('{} requires {} to be specified', *pair) + + def check_properties(groups): + grammar = property_grammar() + for matches, props in groups: +- prop_names = set() ++ seen_props = {} + for prop in props: + # print('--', prop) + prop = prop.partition('#')[0].rstrip() +@@ -214,30 +289,35 @@ def check_properties(groups): + error('Failed to parse: {!r}', prop) + continue + # print('{!r}'.format(parsed)) +- if parsed.NAME in prop_names: ++ if parsed.NAME in seen_props: + error('Property {} is duplicated', parsed.NAME) +- prop_names.add(parsed.NAME) ++ seen_props[parsed.NAME] = parsed.VALUE + if parsed.NAME == 'MOUSE_DPI': + check_one_default(prop, parsed.VALUE.SETTINGS) + elif parsed.NAME == 'ACCEL_MOUNT_MATRIX': + check_one_mount_matrix(prop, parsed.VALUE) + elif parsed.NAME.startswith('KEYBOARD_KEY_'): +- check_one_keycode(prop, parsed.VALUE) ++ val = parsed.VALUE if isinstance(parsed.VALUE, str) else parsed.VALUE[0] ++ check_one_keycode(prop, val) ++ ++ check_wheel_clicks(seen_props) + + def print_summary(fname, groups): ++ n_matches = sum(len(matches) for matches, props in groups) ++ n_props = sum(len(props) for matches, props in groups) + print('{}: {} match groups, {} matches, {} properties' +- .format(fname, +- len(groups), +- sum(len(matches) for matches, props in groups), +- sum(len(props) for matches, props in groups))) ++ .format(fname, len(groups), n_matches, n_props)) ++ ++ if n_matches == 0 or n_props == 0: ++ error('{}: no matches or props'.format(fname)) + + if __name__ == '__main__': +- args = sys.argv[1:] or glob.glob(os.path.dirname(sys.argv[0]) + '/[67]0-*.hwdb') ++ args = sys.argv[1:] or sorted(glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb')) + + for fname in args: + groups = parse(fname) + print_summary(fname, groups) +- check_match_uniqueness(groups) ++ check_matches(groups) + check_properties(groups) + + sys.exit(ERROR) diff --git a/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch b/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch new file mode 100644 index 0000000..7d81489 --- /dev/null +++ b/20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch @@ -0,0 +1,26 @@ +From 62f8dac80e5f908f83b6e7cd06629055184c25d7 Mon Sep 17 00:00:00 2001 +From: Forrestly +Date: Thu, 23 Mar 2023 10:08:33 +0800 +Subject: [PATCH] cgroup: do not refresh cgroup devices config when + daemon-reload(#42937798) + +Signed-off-by: Forrestly +--- + src/core/cgroup.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 50d2738..ea92aa6 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1920,6 +1920,7 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) { + enable_mask = unit_get_enable_mask(u); + needs_bpf = unit_get_needs_bpf(u); + ++ target_mask &= ~CGROUP_MASK_DEVICES; + if (unit_has_mask_realized(u, target_mask, enable_mask, needs_bpf)) + return 0; + +-- +2.34.1 + diff --git a/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch b/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch new file mode 100644 index 0000000..21c5557 --- /dev/null +++ b/20003-core-introduce-cgroup-full-delegation-for-compabilit.patch @@ -0,0 +1,133 @@ +From f25124fabe1ed973840291d46549af6e1c5fad56 Mon Sep 17 00:00:00 2001 +From: "zhongling.h" +Date: Fri, 4 Aug 2023 10:08:16 +0800 +Subject: [PATCH] core: introduce cgroup full delegation for compability + +While using systemd-219, users can set 'delegate=y' to claim the +possession of cgroup settings. By then, users are able to write raw +values under /sys/fs/cgroup to adjust cgroup settings and systemd +won't touch these values any longer. + +However, this is likely to be an undefined behaviour for systemd-219. +Upon releasing systemd-239, a documentation of cgroup delegation was +added, +https://github.com/systemd/systemd/commit/e30eaff3a32523b09d61af67fc999f1f62f4e0cb. +It states that: + +Only sub-trees can be delegated (though whoever decides to request a +sub-tree can delegate sub-sub-trees further to somebody else if they +like it).' + +Which is quite different from what people understand the delegation of +systemd-219. Currently, whether a unit is delegated or not, systemd always +possesses any cgroup it created, only ignoring the sub-tree ones +according to delegation settings. + +This behaviour change causes confusion if users switch from systemd-219 to +systemd-239. As a result, we introduce 'FullDelegation', a feature that +brings what users are already familiar with to systemd-239. If users set +'FullDelegation=yes' in /etc/systemd/system.conf, they can control raw +values under /sys/fs/cgroup without worrying systemd touching these +values, which is the same as what they expected with systemd-219. + +--- + src/core/cgroup.c | 16 ++++++++++++++++ + src/core/main.c | 4 ++++ + src/core/manager.h | 1 + + src/core/system.conf.in | 1 + + 4 files changed, 22 insertions(+) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index ea92aa6f7b..17e3b90e37 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1692,6 +1692,15 @@ static int unit_create_cgroup( + /* Keep track that this is now realized */ + u->cgroup_realized = true; + u->cgroup_realized_mask = target_mask; ++ ++ // While realizing cgroup, we don't realize delegated cgroup, therefore, target_mask ++ // doesn't contain delegated cgroup controller bit, and u->cgroup_realized_mask will ++ // not contain delegated cgroup controller bit as well. This unit will be in a state ++ // as if delegated cgroup is not set, which is not expected. ++ // If this is not present, delegated cgroup will be set every 2 systemctl daemon-reload ++ if (u->manager->full_delegation && unit_cgroup_delegate(u)) ++ u->cgroup_realized_mask |= unit_get_delegate_mask(u); ++ + u->cgroup_enabled_mask = enable_mask; + u->cgroup_bpf_state = needs_bpf ? UNIT_CGROUP_BPF_ON : UNIT_CGROUP_BPF_OFF; + +@@ -1921,6 +1930,10 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) { + needs_bpf = unit_get_needs_bpf(u); + + target_mask &= ~CGROUP_MASK_DEVICES; ++ ++ if (u->manager->full_delegation && unit_cgroup_delegate(u)) ++ target_mask ^= u->cgroup_realized_mask; ++ + if (unit_has_mask_realized(u, target_mask, enable_mask, needs_bpf)) + return 0; + +@@ -2883,6 +2896,9 @@ int unit_reset_ip_accounting(Unit *u) { + void unit_invalidate_cgroup(Unit *u, CGroupMask m) { + assert(u); + ++ if (u->manager->full_delegation) ++ m ^= unit_get_delegate_mask(u); // don't invalidate delegated cgroup ++ + if (!UNIT_HAS_CGROUP_CONTEXT(u)) + return; + +diff --git a/src/core/main.c b/src/core/main.c +index 546bf0d870..68daf07077 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -142,6 +142,7 @@ static bool reexec_jmp_can = false; + static bool reexec_jmp_inited = false; + static sigjmp_buf reexec_jmp_buf; + static bool arg_default_cpuset_clone_children = false; ++static bool arg_full_delegation = false; + + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); +@@ -768,6 +769,8 @@ static int parse_config_file(void) { + { "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max }, + { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action }, + { "Manager", "DefaultCPUSetCloneChildren",config_parse_bool, 0, &arg_default_cpuset_clone_children }, ++ { "Manager", "FullDelegation", config_parse_bool, 0, &arg_full_delegation }, ++ + {} + }; + +@@ -817,6 +820,7 @@ static void set_manager_defaults(Manager *m) { + m->default_memory_accounting = arg_default_memory_accounting; + m->default_tasks_accounting = arg_default_tasks_accounting; + m->default_tasks_max = arg_default_tasks_max; ++ m->full_delegation = arg_full_delegation; + + manager_set_default_rlimits(m, arg_default_rlimit); + manager_environment_add(m, NULL, arg_default_environment); +diff --git a/src/core/manager.h b/src/core/manager.h +index 98d381bc5b..91f2c05afe 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -297,6 +297,7 @@ struct Manager { + bool default_blockio_accounting; + bool default_tasks_accounting; + bool default_ip_accounting; ++ bool full_delegation; + + uint64_t default_tasks_max; + usec_t default_timer_accuracy_usec; +diff --git a/src/core/system.conf.in b/src/core/system.conf.in +index 2f6852a89f..6c84a55401 100644 +--- a/src/core/system.conf.in ++++ b/src/core/system.conf.in +@@ -67,3 +67,4 @@ DefaultLimitCORE=0:infinity + #DefaultLimitRTTIME= + #IPAddressAllow= + #IPAddressDeny= ++#FullDelegation=no +-- +2.39.3 + diff --git a/systemd.spec b/systemd.spec index 465fe17..f6838df 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1058,6 +1058,10 @@ Patch10023: 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch Patch10024: 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch Patch10025: 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch +Patch20001: 20001-hwdb-parse_hwdb_dot_py.patch +Patch20002: 20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch +Patch20003: 20003-core-introduce-cgroup-full-delegation-for-compabilit.patch + %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 %endif @@ -1716,6 +1720,9 @@ fi - fileio: beef up READ_FULL_FILE_CONNECT_SOCKET to allow setting sender socket name (Guorui Yu) - fileio: teach read_full_file_full() to read from offset/with maximum size (Guorui Yu) - cryptsetup: port cryptsetup's main key file logic over to read_full_file_full() (Guorui Yu) +- Update upstream parse_hwdb.py to fix parse-hwdb error (Zhongling He) +- cgroup: do not refresh cgroup devices config when daemon-reload (Zhongling He) +- core: introduce cgroup full delegation for compability (Zhongling He) * Tue Aug 22 2023 systemd maintenance team - 239-78 - login: add a missing error check for session_set_leader() (#2158167) -- Gitee From a189fc3771f781bdd872a6c4ba4a1dcea2175cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=A0=E5=87=8C?= Date: Tue, 12 Dec 2023 17:04:38 +0800 Subject: [PATCH 10/11] standarize patch number of cherry-picked patch 0914->10026 --- ...-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch | 3 +++ systemd.spec | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) rename 0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch => 10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch (95%) diff --git a/0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch b/10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch similarity index 95% rename from 0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch rename to 10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch index c24ff51..fbc76ac 100644 --- a/0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch +++ b/10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch @@ -7,6 +7,9 @@ Subject: [PATCH] umount: check LO_FLAGS_AUTOCLEAR after LOOP_CLR_FD claimed Fixes: #14410 Replaces: #14386 +For Lifsea-ng, this patch fixes the problem that the system occasionally +fail to shutdown caused by /sysroot unable to umount. + --- systemd-239/src/core/umount.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/systemd.spec b/systemd.spec index f6838df..3d7c723 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1030,7 +1030,6 @@ Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch -Patch0980: 0980-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch Patch10000: 10000-core-fix-a-null-reference-case-in-load_from_path.patch Patch10001: 10001-sysctl-Don-t-pass-null-directive-argument-to-s.patch Patch10002: 10002-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch @@ -1057,6 +1056,7 @@ Patch10022: 10022-fileio-add-support-for-read_full_file-on-AF_UNIX-st.patch Patch10023: 10023-fileio-beef-up-READ_FULL_FILE_CONNECT_SOCKET-to-all.patch Patch10024: 10024-fileio-teach-read_full_file_full-to-read-from-offse.patch Patch10025: 10025-cryptsetup-port-cryptsetup-s-main-key-file-logic-ov.patch +Patch10026: 10026-umount-check-LO_FLAGS_AUTOCLEAR-after-LOOP_CLR_FD-cl.patch Patch20001: 20001-hwdb-parse_hwdb_dot_py.patch Patch20002: 20002-cgroup-do-not-refresh-cgroup-devices-config-when-dae.patch -- Gitee From ed63a7ffb80086a14367370f0348b124750ceb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=A0=E5=87=8C?= Date: Tue, 12 Dec 2023 17:15:44 +0800 Subject: [PATCH 11/11] add README.md to especially address patch indexing convention --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d30ca3 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# systemd-239 + +This is the repository of systemd-239 for Anolis OS 8. + +## Patch index convention + +Below is the patch index convention of this repository: + +- 0001 ... 0xxx : patches from upstream srpm +- 10001 ... 10xxx : patches cherry-picked from systemd github upstream +- 20001 ... 20xxx : original patch by OpenAnolis community \ No newline at end of file -- Gitee