diff --git a/SOURCES/0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch b/SOURCES/0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch new file mode 100644 index 0000000..caba846 --- /dev/null +++ b/SOURCES/0905-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch @@ -0,0 +1,113 @@ +From e0488facf5b6e1faa292460548cfe0d7c542918d 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 + +Some extra safety when invoked via "sudo". With this we address a +genuine design flaw of sudo, and we shouldn't need to deal with this. +But it's still a good idea to disable this surface given how exotic it +is. + +Prompted by #5666 + +(cherry picked from commit 612ebf6c913dd0e4197c44909cb3157f5c51a2f0) + +Related: #2175623 +--- + man/less-variables.xml | 8 ++++++++ + man/systemctl.xml | 1 + + man/systemd.xml | 2 ++ + src/basic/pager.c | 23 +++++++++++++++++++++-- + 4 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index a3faa38997..9dad4247da 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -36,5 +36,13 @@ + the invoking terminal is determined to be UTF-8 compatible). + + ++ ++ $SYSTEMD_LESSSECURE ++ ++ Takes a boolean argument. Overrides the $LESSSECURE environment ++ variable when invoking the pager, which controls the "secure" mode of less (which disables commands ++ such as | which allow to easily shell out to external command lines). By default ++ less secure mode is enabled, with this setting it may be disabled. ++ + + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index a71e6c7c4f..abc386e6fb 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2010,6 +2010,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + ++ + + + +diff --git a/man/systemd.xml b/man/systemd.xml +index 17ab59beb5..66ae4d841d 100644 +--- a/man/systemd.xml ++++ b/man/systemd.xml +@@ -862,6 +862,8 @@ + + + ++ ++ + + $LISTEN_PID + $LISTEN_FDS +diff --git a/src/basic/pager.c b/src/basic/pager.c +index f241261119..4efb01c483 100644 +--- a/src/basic/pager.c ++++ b/src/basic/pager.c +@@ -11,6 +11,7 @@ + #include + + #include "copy.h" ++#include "env-util.h" + #include "fd-util.h" + #include "locale-util.h" + #include "log.h" +@@ -94,8 +95,7 @@ int pager_open(bool no_pager, bool jump_to_end) { + if (setenv("LESS", less_opts, 1) < 0) + _exit(EXIT_FAILURE); + +- /* Initialize a good charset for less. This is +- * particularly important if we output UTF-8 ++ /* Initialize a good charset for less. This is particularly important if we output UTF-8 + * characters. */ + less_charset = getenv("SYSTEMD_LESSCHARSET"); + if (!less_charset && is_locale_utf8()) +@@ -104,6 +104,25 @@ int pager_open(bool no_pager, bool jump_to_end) { + setenv("LESSCHARSET", less_charset, 1) < 0) + _exit(EXIT_FAILURE); + ++ /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out ++ * privileged stuff. */ ++ r = getenv_bool("SYSTEMD_LESSSECURE"); ++ if (r == 0) { /* Remove env var if off */ ++ if (unsetenv("LESSSECURE") < 0) { ++ log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); ++ } ++ } else { ++ /* Set env var otherwise */ ++ if (r < 0) ++ log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m"); ++ ++ if (setenv("LESSSECURE", "1", 1) < 0) { ++ log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); ++ } ++ } ++ + if (pager) { + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); diff --git a/SOURCES/0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch b/SOURCES/0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch new file mode 100644 index 0000000..b1691c3 --- /dev/null +++ b/SOURCES/0906-test-login-always-test-sd_pid_get_owner_uid-moderniz.patch @@ -0,0 +1,264 @@ +From cd2d72208df18c0894d2e6eea0656603e326f9cf 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 + +A long time some function only worked when in a session, and the test +didn't execute them when sd_pid_get_session() failed. Let's always call +them to increase coverage. + +While at it, let's test for ==0 not >=0 where we don't expect the function +to return anything except 0 or error. + +(cherry picked from commit 1b5b507cd2d1d7a2b053151abb548475ad9c5c3b) + +Related: #2175623 +--- + src/libsystemd/sd-login/test-login.c | 132 ++++++++++++++------------- + 1 file changed, 71 insertions(+), 61 deletions(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index ccb1905a46..60ef889ec0 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -8,20 +8,22 @@ + #include "sd-login.h" + + #include "alloc-util.h" ++#include "errno-list.h" + #include "fd-util.h" + #include "format-util.h" + #include "log.h" + #include "string-util.h" + #include "strv.h" +-#include "util.h" ++#include "time-util.h" ++#include "user-util.h" + + static char* format_uids(char **buf, uid_t* uids, int count) { +- int pos = 0, k, inc; ++ int pos = 0, inc; + size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1; + + assert_se(*buf = malloc(size)); + +- for (k = 0; k < count; k++) { ++ for (int k = 0; k < count; k++) { + sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc); + pos += inc; + } +@@ -32,6 +34,10 @@ static char* format_uids(char **buf, uid_t* uids, int count) { + return *buf; + } + ++static const char *e(int r) { ++ return r == 0 ? "OK" : errno_to_name(r); ++} ++ + static void test_login(void) { + _cleanup_close_pair_ int pair[2] = { -1, -1 }; + _cleanup_free_ char *pp = NULL, *qq = NULL, +@@ -41,65 +47,71 @@ static void test_login(void) { + *seat = NULL, *session = NULL, + *unit = NULL, *user_unit = NULL, *slice = NULL; + int r; +- uid_t u, u2; +- char *t, **seats, **sessions; ++ uid_t u, u2 = UID_INVALID; ++ char *t, **seats = NULL, **sessions = NULL; + + r = sd_pid_get_unit(0, &unit); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit)); ++ log_info("sd_pid_get_unit(0, …) → %s / \"%s\"", e(r), strnull(unit)); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_user_unit(0, &user_unit); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit)); ++ log_info("sd_pid_get_user_unit(0, …) → %s / \"%s\"", e(r), strnull(user_unit)); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_slice(0, &slice); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice)); ++ log_info("sd_pid_get_slice(0, …) → %s / \"%s\"", e(r), strnull(slice)); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ ++ r = sd_pid_get_owner_uid(0, &u2); ++ log_info("sd_pid_get_owner_uid(0, …) → %s / "UID_FMT, e(r), u2); ++ assert_se(IN_SET(r, 0, -ENODATA)); + + r = sd_pid_get_session(0, &session); +- if (r < 0) { +- log_warning_errno(r, "sd_pid_get_session(0, …): %m"); +- if (r == -ENODATA) +- log_info("Seems we are not running in a session, skipping some tests."); +- } else { +- log_info("sd_pid_get_session(0, …) → \"%s\"", session); +- +- assert_se(sd_pid_get_owner_uid(0, &u2) == 0); +- log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2); +- +- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0); +- log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup); +- +- r = sd_uid_get_display(u2, &display_session); +- assert_se(r >= 0 || r == -ENODATA); +- log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"", +- u2, strnull(display_session)); +- +- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); +- sd_peer_get_session(pair[0], &pp); +- sd_peer_get_session(pair[1], &qq); +- assert_se(streq_ptr(pp, qq)); +- +- r = sd_uid_get_sessions(u2, false, &sessions); ++ log_info("sd_pid_get_session(0, …) → %s / \"%s\"", e(r), strnull(session)); ++ ++ r = sd_pid_get_cgroup(0, &cgroup); ++ log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup)); ++ assert_se(r == 0); ++ ++ r = sd_uid_get_display(u2, &display_session); ++ log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session)); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ ++ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); ++ sd_peer_get_session(pair[0], &pp); ++ sd_peer_get_session(pair[1], &qq); ++ assert_se(streq_ptr(pp, qq)); ++ ++ r = sd_uid_get_sessions(u2, false, &sessions); ++ assert_se(t = strv_join(sessions, " ")); ++ log_info("sd_uid_get_sessions("UID_FMT", …) → %s \"%s\"", u2, e(r), t); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else { + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); +- assert_se(t = strv_join(sessions, " ")); +- strv_free(sessions); +- log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t); +- free(t); ++ } ++ sessions = strv_free(sessions); ++ free(t); + +- assert_se(r == sd_uid_get_sessions(u2, false, NULL)); ++ assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + +- r = sd_uid_get_seats(u2, false, &seats); ++ r = sd_uid_get_seats(u2, false, &seats); ++ assert_se(t = strv_join(seats, " ")); ++ log_info("sd_uid_get_seats("UID_FMT", …) → %s \"%s\"", u2, e(r), t); ++ if (u2 == UID_INVALID) ++ assert_se(r == -EINVAL); ++ else { + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); +- assert_se(t = strv_join(seats, " ")); +- strv_free(seats); +- log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t); +- free(t); +- +- assert_se(r == sd_uid_get_seats(u2, false, NULL)); + } ++ seats = strv_free(seats); ++ free(t); ++ ++ assert_se(r == sd_uid_get_seats(u2, false, NULL)); + + if (session) { + r = sd_session_is_active(session); +@@ -111,7 +123,7 @@ static void test_login(void) { + log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); + + r = sd_session_get_state(session, &state); +- assert_se(r >= 0); ++ assert_se(r == 0); + log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); + + assert_se(sd_session_get_uid(session, &u) >= 0); +@@ -125,16 +137,16 @@ static void test_login(void) { + log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); + + r = sd_session_get_display(session, &display); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); + + r = sd_session_get_remote_user(session, &remote_user); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", + session, strna(remote_user)); + + r = sd_session_get_remote_host(session, &remote_host); +- assert_se(r >= 0 || r == -ENODATA); ++ assert_se(IN_SET(r, 0, -ENODATA)); + log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", + session, strna(remote_host)); + +@@ -160,7 +172,7 @@ static void test_login(void) { + assert_se(r == -ENODATA); + } + +- assert_se(sd_uid_get_state(u, &state2) >= 0); ++ assert_se(sd_uid_get_state(u, &state2) == 0); + log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); + } + +@@ -172,11 +184,11 @@ static void test_login(void) { + assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + + r = sd_seat_get_active(seat, &session2, &u2); +- assert_se(r >= 0); ++ assert_se(r == 0); + log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2); + + r = sd_uid_is_on_seat(u, 1, seat); +- assert_se(r >= 0); ++ assert_se(IN_SET(r, 0, 1)); + assert_se(!!r == streq(session, session2)); + + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); +@@ -184,8 +196,8 @@ static void test_login(void) { + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, " ")); + strv_free(sessions); +- log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}", +- seat, r, t, n, format_uids(&buf, uids, n)); ++ log_info("sd_seat_get_sessions(\"%s\", …) → %s, \"%s\", [%u] {%s}", ++ seat, e(r), t, n, format_uids(&buf, uids, n)); + free(t); + + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); +@@ -203,7 +215,7 @@ static void test_login(void) { + + r = sd_seat_get_active(NULL, &t, NULL); + assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t)); ++ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t)); + free(t); + + r = sd_get_sessions(&sessions); +@@ -243,13 +255,11 @@ static void test_login(void) { + + static void test_monitor(void) { + sd_login_monitor *m = NULL; +- unsigned n; + int r; + +- r = sd_login_monitor_new("session", &m); +- assert_se(r >= 0); ++ assert_se(sd_login_monitor_new("session", &m) == 0); + +- for (n = 0; n < 5; n++) { ++ for (unsigned n = 0; n < 5; n++) { + struct pollfd pollfd = {}; + usec_t timeout, nw; + diff --git a/SOURCES/0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch b/SOURCES/0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch new file mode 100644 index 0000000..543ff64 --- /dev/null +++ b/SOURCES/0907-pager-make-pager-secure-when-under-euid-is-changed-o.patch @@ -0,0 +1,198 @@ +From 9c8a6018ed4a4da6efb1fc6958e70f9324bb5b1e 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 + explicitly requested + +The variable is renamed to SYSTEMD_PAGERSECURE (because it's not just about +less now), and we automatically enable secure mode in certain cases, but not +otherwise. + +This approach is more nuanced, but should provide a better experience for +users: + +- Previusly we would set LESSSECURE=1 and trust the pager to make use of + it. But this has an effect only on less. We need to not start pagers which + are insecure when in secure mode. In particular more is like that and is a + very popular pager. + +- We don't enable secure mode always, which means that those other pagers can + reasonably used. + +- We do the right thing by default, but the user has ultimate control by + setting SYSTEMD_PAGERSECURE. + +Fixes #5666. + +v2: +- also check $PKEXEC_UID + +v3: +- use 'sd_pid_get_owner_uid() != geteuid()' as the condition + +(cherry picked from commit 0a42426d797406b4b01a0d9c13bb759c2629d108) + +Resolves: #2175623 +--- + man/less-variables.xml | 28 ++++++++++++++--- + meson.build | 3 +- + src/basic/pager.c | 69 +++++++++++++++++++++++++++--------------- + 3 files changed, 69 insertions(+), 31 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index 9dad4247da..5f3a53c8dd 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -37,12 +37,30 @@ + + + +- $SYSTEMD_LESSSECURE ++ $SYSTEMD_PAGERSECURE + +- Takes a boolean argument. Overrides the $LESSSECURE environment +- variable when invoking the pager, which controls the "secure" mode of less (which disables commands +- such as | which allow to easily shell out to external command lines). By default +- less secure mode is enabled, with this setting it may be disabled. ++ Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if ++ false, disabled. If $SYSTEMD_PAGERSECURE is not set at all, secure mode is enabled ++ if the effective UID is not the same as the owner of the login session, see geteuid2 and ++ sd_pid_get_owner_uid3. ++ In secure mode, will be set when invoking the pager, and the pager shall ++ disable commands that open or create new files or start new subprocesses. When ++ $SYSTEMD_PAGERSECURE is not set at all, pagers which are not known to implement ++ secure mode will not be used. (Currently only ++ less1 implements ++ secure mode.) ++ ++ Note: when commands are invoked with elevated privileges, for example under sudo8 or ++ pkexec1, care ++ must be taken to ensure that unintended interactive features are not enabled. "Secure" mode for the ++ pager may be enabled automatically as describe above. Setting SYSTEMD_PAGERSECURE=0 ++ or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note ++ that if the $SYSTEMD_PAGER or $PAGER variables are to be ++ honoured, $SYSTEMD_PAGERSECURE must be set too. It might be reasonable to completly ++ disable the pager using instead. + + + +diff --git a/meson.build b/meson.build +index 673800a1a7..d986dd24ac 100644 +--- a/meson.build ++++ b/meson.build +@@ -1467,7 +1467,8 @@ test_dlopen = executable( + 'test-dlopen', + test_dlopen_c, + include_directories : includes, +- link_with : [libbasic], ++ link_with : [libsystemd_static, ++ libbasic], + dependencies : [libdl]) + + foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'], +diff --git a/src/basic/pager.c b/src/basic/pager.c +index 4efb01c483..c7e101235d 100644 +--- a/src/basic/pager.c ++++ b/src/basic/pager.c +@@ -10,6 +10,8 @@ + #include + #include + ++#include "sd-login.h" ++ + #include "copy.h" + #include "env-util.h" + #include "fd-util.h" +@@ -79,7 +81,7 @@ int pager_open(bool no_pager, bool jump_to_end) { + if (r < 0) + return r; + if (r == 0) { +- const char* less_opts, *less_charset; ++ const char* less_opts, *less_charset, *exe; + + /* In the child start the pager */ + +@@ -105,39 +107,56 @@ int pager_open(bool no_pager, bool jump_to_end) { + _exit(EXIT_FAILURE); + + /* People might invoke us from sudo, don't needlessly allow less to be a way to shell out +- * privileged stuff. */ +- r = getenv_bool("SYSTEMD_LESSSECURE"); +- if (r == 0) { /* Remove env var if off */ +- if (unsetenv("LESSSECURE") < 0) { +- log_error_errno(errno, "Failed to uset environment variable LESSSECURE: %m"); +- _exit(EXIT_FAILURE); +- } +- } else { +- /* Set env var otherwise */ ++ * privileged stuff. If the user set $SYSTEMD_PAGERSECURE, trust their configuration of the ++ * pager. If they didn't, use secure mode when under euid is changed. If $SYSTEMD_PAGERSECURE ++ * wasn't explicitly set, and we autodetect the need for secure mode, only use the pager we ++ * know to be good. */ ++ int use_secure_mode = getenv_bool("SYSTEMD_PAGERSECURE"); ++ bool trust_pager = use_secure_mode >= 0; ++ if (use_secure_mode == -ENXIO) { ++ uid_t uid; ++ ++ r = sd_pid_get_owner_uid(0, &uid); + if (r < 0) +- log_warning_errno(r, "Unable to parse $SYSTEMD_LESSSECURE, ignoring: %m"); ++ log_debug_errno(r, "sd_pid_get_owner_uid() failed, enabling pager secure mode: %m"); ++ ++ use_secure_mode = r < 0 || uid != geteuid(); ++ ++ } else if (use_secure_mode < 0) { ++ log_warning_errno(use_secure_mode, "Unable to parse $SYSTEMD_PAGERSECURE, assuming true: %m"); ++ use_secure_mode = true; ++ } + +- if (setenv("LESSSECURE", "1", 1) < 0) { +- log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m"); +- _exit(EXIT_FAILURE); +- } ++ /* We generally always set variables used by less, even if we end up using a different pager. ++ * They shouldn't hurt in any case, and ideally other pagers would look at them too. */ ++ if (use_secure_mode) ++ r = setenv("LESSSECURE", "1", 1); ++ else ++ r = unsetenv("LESSSECURE"); ++ if (r < 0) { ++ log_error_errno(errno, "Failed to adjust environment variable LESSSECURE: %m"); ++ _exit(EXIT_FAILURE); + } + +- if (pager) { ++ if (trust_pager && pager) { /* The pager config might be set globally, and we cannot ++ * know if the user adjusted it to be appropriate for the ++ * secure mode. Thus, start the pager specified through ++ * envvars only when $SYSTEMD_PAGERSECURE was explicitly set ++ * as well. */ + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); + } + +- /* Debian's alternatives command for pagers is +- * called 'pager'. Note that we do not call +- * sensible-pagers here, since that is just a +- * shell script that implements a logic that +- * is similar to this one anyway, but is +- * Debian-specific. */ +- execlp("pager", "pager", NULL); ++ /* Debian's alternatives command for pagers is called 'pager'. Note that we do not call ++ * sensible-pagers here, since that is just a shell script that implements a logic that is ++ * similar to this one anyway, but is Debian-specific. */ ++ FOREACH_STRING(exe, "pager", "less", "more") { ++ /* Only less implements secure mode right now. */ ++ if (use_secure_mode && !streq(exe, "less")) ++ continue; + +- execlp("less", "less", NULL); +- execlp("more", "more", NULL); ++ execlp(exe, exe, NULL); ++ } + + pager_fallback(); + /* not reached */ diff --git a/SOURCES/0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch b/SOURCES/0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch new file mode 100644 index 0000000..405232b --- /dev/null +++ b/SOURCES/0908-test-ignore-ENOMEDIUM-error-from-sd_pid_get_cgroup.patch @@ -0,0 +1,30 @@ +From 1d8931bb5d65e9f77b470835786a97f814bd93ea 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() + +Ubuntu builds on the Launchpad infrastructure run inside a chroot that does +not have the sysfs cgroup dirs mounted, so this call will return ENOMEDIUM +from cg_unified_cached() during the build-time testing, for example when +building the package in a Launchpad PPA. + +(cherry picked from commit 352ab9d74049b4ac694fdba1a6e67339f12ded93) + +Related: #2175623 +--- + src/libsystemd/sd-login/test-login.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index 60ef889ec0..d24a04ccc8 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -71,7 +71,7 @@ static void test_login(void) { + + r = sd_pid_get_cgroup(0, &cgroup); + log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup)); +- assert_se(r == 0); ++ assert_se(IN_SET(r, 0, -ENOMEDIUM)); + + r = sd_uid_get_display(u2, &display_session); + log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session)); diff --git a/SOURCES/0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch b/SOURCES/0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch new file mode 100644 index 0000000..588c30f --- /dev/null +++ b/SOURCES/0909-pstore-fix-crash-and-forward-dummy-arguments-instead.patch @@ -0,0 +1,31 @@ +From 5bb3dd9c96b55a4a9da23ed96b5a2681d82dc500 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 + +[msekleta: in our version of systemd "const char path*" argument of +path_join() can't be NULL. Here we don't really want any subdirs paths +passed into move_file(), but we can't just pass NULL pointers because +they will be forwarded to path_join(). Hence, let's just pass "/" +instead.] + +rhel-only + +Related: #2190153 +--- + src/pstore/pstore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c +index 9f61e8f7f8..5335c9f92d 100644 +--- a/src/pstore/pstore.c ++++ b/src/pstore/pstore.c +@@ -366,7 +366,7 @@ static int run(int argc, char *argv[]) { + + /* Move left over files out of pstore */ + for (size_t n = 0; n < list.n_entries; n++) +- (void) move_file(&list.entries[n], NULL, NULL); ++ (void) move_file(&list.entries[n], "/", "/"); + + return 0; + } diff --git a/SOURCES/0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch b/SOURCES/0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch new file mode 100644 index 0000000..3b3abf3 --- /dev/null +++ b/SOURCES/0910-ci-workflow-for-gathering-metadata-for-source-git-au.patch @@ -0,0 +1,51 @@ +From d78272e6c2dddcbca891cb5d561f23ff766486a8 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 + +Workflow gathers metadata like pull request numbers and information about commits. +This metadata is used for commit validation and other actions. +This workflow also triggers for rest of the source-git automation workflows. + +rhel-only + +Related: #2190153 +--- + .github/workflows/gather-metadata.yml | 28 +++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + create mode 100644 .github/workflows/gather-metadata.yml + +diff --git a/.github/workflows/gather-metadata.yml b/.github/workflows/gather-metadata.yml +new file mode 100644 +index 0000000000..f432f41811 +--- /dev/null ++++ b/.github/workflows/gather-metadata.yml +@@ -0,0 +1,28 @@ ++name: Gather Pull Request Metadata ++on: ++ pull_request: ++ types: [ opened, reopened, synchronize ] ++ branches: ++ - main ++ - rhel-8.*.0 ++ ++permissions: ++ contents: read ++ ++jobs: ++ gather-metadata: ++ runs-on: ubuntu-latest ++ ++ steps: ++ - name: Repository checkout ++ uses: actions/checkout@v3 ++ ++ - id: Metadata ++ name: Gather Pull Request Metadata ++ uses: redhat-plumbers-in-action/gather-pull-request-metadata@v1 ++ ++ - name: Upload artifact with gathered metadata ++ uses: actions/upload-artifact@v3 ++ with: ++ name: pr-metadata ++ path: ${{ steps.Metadata.outputs.metadata-file }} diff --git a/SOURCES/0911-ci-first-part-of-the-source-git-automation-commit-li.patch b/SOURCES/0911-ci-first-part-of-the-source-git-automation-commit-li.patch new file mode 100644 index 0000000..e6dc994 --- /dev/null +++ b/SOURCES/0911-ci-first-part-of-the-source-git-automation-commit-li.patch @@ -0,0 +1,103 @@ +From e08bdd25344ed475f48d22a1c303421e19489427 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 + +Add a GitHub Workflow that is triggered on `workflow_run` events. +It uses metadata provided by `redhat-plumbers-in-action/gather-pull-request-metadata` +GitHub Action to get the PR number and the commit metadata. +The commit metadata is then used to check if the commit message contains +all required information (tracker and upstream reference). GitHub Action +responsible for commit verification `redhat-plumbers-in-action/advanced-commit-linter` +is configured via the `advanced-commit-linter.yml` file. + +rhel-only + +Related: #2190153 +--- + .github/advanced-commit-linter.yml | 23 +++++++++++ + .github/workflows/source-git-automation.yml | 45 +++++++++++++++++++++ + 2 files changed, 68 insertions(+) + create mode 100644 .github/advanced-commit-linter.yml + create mode 100644 .github/workflows/source-git-automation.yml + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +new file mode 100644 +index 0000000000..491836abbb +--- /dev/null ++++ b/.github/advanced-commit-linter.yml +@@ -0,0 +1,23 @@ ++policy: ++ cherry-pick: ++ upstream: ++ - github: systemd/systemd ++ - github: systemd/systemd-stable ++ exception: ++ note: ++ - rhel-only ++ tracker: ++ - keyword: ++ - 'Resolves: #?' ++ - 'Related: #?' ++ - 'Reverts: #?' ++ issue-format: ++ - '\d+$' ++ url: 'https://bugzilla.redhat.com/show_bug.cgi?id=' ++ - keyword: ++ - 'Resolves: ' ++ - 'Related: ' ++ - 'Reverts: ' ++ issue-format: ++ - 'RHEL-\d+$' ++ url: 'https://issues.redhat.com/browse/' +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +new file mode 100644 +index 0000000000..140f21b116 +--- /dev/null ++++ b/.github/workflows/source-git-automation.yml +@@ -0,0 +1,45 @@ ++name: Source git Automation ++on: ++ workflow_run: ++ workflows: [ Gather Pull Request Metadata ] ++ types: ++ - completed ++ ++permissions: ++ contents: read ++ ++jobs: ++ download-metadata: ++ if: > ++ github.event.workflow_run.event == 'pull_request' && ++ github.event.workflow_run.conclusion == 'success' ++ runs-on: ubuntu-latest ++ ++ outputs: ++ pr-metadata: ${{ steps.Artifact.outputs.pr-metadata-json }} ++ ++ steps: ++ - id: Artifact ++ name: Download Artifact ++ uses: redhat-plumbers-in-action/download-artifact@v1 ++ with: ++ name: pr-metadata ++ ++ commit-linter: ++ needs: [ download-metadata ] ++ runs-on: ubuntu-latest ++ ++ outputs: ++ validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} ++ ++ permissions: ++ statuses: write ++ pull-requests: write ++ ++ steps: ++ - id: commit-linter ++ name: Lint Commits ++ uses: redhat-plumbers-in-action/advanced-commit-linter@v1 ++ with: ++ pr-metadata: ${{ needs.download-metadata.outputs.pr-metadata }} ++ token: ${{ secrets.GITHUB_TOKEN }} diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index da5b57f..34f5865 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 74%{?dist} +Release: 74%{?dist}.2 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -954,6 +954,13 @@ 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 %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1584,6 +1591,17 @@ fi %files tests -f .file-list-tests %changelog +* 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 Mar 14 2023 systemd maintenance team - 239-74 - journald-server: always create state file in signal handler (#2174645) - journald-server: move relinquish code into function (#2174645)