diff options
6 files changed, 418 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index 3766b2e..70d04c3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +systemd (241-7~deb10u9) buster-security; urgency=medium + + * Non-maintainer upload by the LTS Security Team. + * CVE-2023-26604: Local privilege escalation for some sudo + configurations. + + -- Adrian Bunk <bunk@debian.org> Thu, 30 Mar 2023 22:32:31 +0300 + systemd (241-7~deb10u8) buster-security; urgency=high * Non-maintainer upload by the Security Team. diff --git a/debian/patches/0001-man-share-description-of-SYSTEMD_COLORS-in-other-too.patch b/debian/patches/0001-man-share-description-of-SYSTEMD_COLORS-in-other-too.patch new file mode 100644 index 0000000..63c24c9 --- /dev/null +++ b/debian/patches/0001-man-share-description-of-SYSTEMD_COLORS-in-other-too.patch @@ -0,0 +1,79 @@ +From 5489d98aa994019e06abd7aa66173a9868a5b1b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Fri, 15 Nov 2019 11:59:34 +0100 +Subject: man: share description of $SYSTEMD_COLORS in other tools + +It was only described in systemd(1), making it hard to discover. +Fixes #13561. + +The same for $SYSTEMD_URLIFY. + +I think all the tools whose man pages include less-variables.xml support +those variables. +--- + man/less-variables.xml | 20 +++++++++++++++++++- + man/systemd.xml | 19 ++----------------- + 2 files changed, 21 insertions(+), 18 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index eb332b56b0..334eb19871 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -42,5 +42,23 @@ + the invoking terminal is determined to be UTF-8 compatible).</para></listitem> + </varlistentry> + +- </variablelist> ++ <varlistentry id='colors'> ++ <term><varname>$SYSTEMD_COLORS</varname></term> ++ ++ <listitem><para>The value must be a boolean. Controls whether colorized output should be ++ generated. This can be specified to override the decision that <command>systemd</command> makes based ++ on <varname>$TERM</varname> and what the console is connected to.</para> ++ </listitem> ++ </varlistentry> ++ ++ <varlistentry id='urlify'> ++ <term><varname>$SYSTEMD_URLIFY</varname></term> ++ ++ <listitem><para>The value must be a boolean. Controls whether clickable links should be generated in ++ the output for terminal emulators supporting this. This can be specified to override the decision that ++ <command>systemd</command> makes based on <varname>$TERM</varname> and other conditions.</para> ++ </listitem> ++ </varlistentry> ++ ++ </variablelist> + </refsect1> +diff --git a/man/systemd.xml b/man/systemd.xml +index 5287bdaba8..1ff1f34dbe 100644 +--- a/man/systemd.xml ++++ b/man/systemd.xml +@@ -873,23 +873,8 @@ + script runlevel link farms.</para></listitem> + </varlistentry> + +- <varlistentry> +- <term><varname>$SYSTEMD_COLORS</varname></term> +- +- <listitem><para>The value must be a boolean. Controls whether colorized output should be +- generated. This can be specified to override the decision that <command>systemd</command> +- makes based on <varname>$TERM</varname> and what the console is connected to.</para> +- </listitem> +- </varlistentry> +- +- <varlistentry> +- <term><varname>$SYSTEMD_URLIFY</varname></term> +- +- <listitem><para>The value must be a boolean. Controls whether clickable links should be generated in the output +- for terminal emulators supporting this. This can be specified to override the decision that +- <command>systemd</command> makes based on <varname>$TERM</varname> and other conditions.</para> +- </listitem> +- </varlistentry> ++ <xi:include href="less-variables.xml" xpointer="colors" /> ++ <xi:include href="less-variables.xml" xpointer="urlify" /> + + <varlistentry> + <term><varname>$LISTEN_PID</varname></term> +-- +2.30.2 + diff --git a/debian/patches/0002-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch b/debian/patches/0002-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch new file mode 100644 index 0000000..4b4ccc3 --- /dev/null +++ b/debian/patches/0002-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch @@ -0,0 +1,112 @@ +From 47bf4e7c6be2f73ecc8cfd8732920987df09e487 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering <lennart@poettering.net> +Date: Mon, 31 Aug 2020 19:37:13 +0200 +Subject: 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 +--- + man/less-variables.xml | 9 +++++++++ + man/systemctl.xml | 1 + + man/systemd.xml | 1 + + src/shared/pager.c | 23 +++++++++++++++++++++-- + 4 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index 334eb19871..fed4178b01 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -60,5 +60,14 @@ + </listitem> + </varlistentry> + ++ <varlistentry id='lesssecure'> ++ <term><varname>$SYSTEMD_LESSSECURE</varname></term> ++ ++ <listitem><para>Takes a boolean argument. Overrides the <varname>$LESSSECURE</varname> environment ++ variable when invoking the pager, which controls the "secure" mode of less (which disables commands ++ such as <literal>|</literal> which allow to easily shell out to external command lines). By default ++ less secure mode is enabled, with this setting it may be disabled.</para></listitem> ++ </varlistentry> ++ + </variablelist> + </refsect1> +diff --git a/man/systemctl.xml b/man/systemctl.xml +index 08aacd8f41..22b26d3607 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2039,6 +2039,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + <xi:include href="less-variables.xml" xpointer="pager"/> + <xi:include href="less-variables.xml" xpointer="less"/> + <xi:include href="less-variables.xml" xpointer="lesscharset"/> ++ <xi:include href="less-variables.xml" xpointer="lesssecure"/> + </refsect1> + + <refsect1> +diff --git a/man/systemd.xml b/man/systemd.xml +index 1ff1f34dbe..d0d847c353 100644 +--- a/man/systemd.xml ++++ b/man/systemd.xml +@@ -875,6 +875,7 @@ + + <xi:include href="less-variables.xml" xpointer="colors" /> + <xi:include href="less-variables.xml" xpointer="urlify" /> ++ <xi:include href="less-variables.xml" xpointer="lesssecure"/> + + <varlistentry> + <term><varname>$LISTEN_PID</varname></term> +diff --git a/src/shared/pager.c b/src/shared/pager.c +index bf2597e65a..7a56271760 100644 +--- a/src/shared/pager.c ++++ b/src/shared/pager.c +@@ -11,6 +11,7 @@ + #include <unistd.h> + + #include "copy.h" ++#include "env-util.h" + #include "fd-util.h" + #include "fileio.h" + #include "io-util.h" +@@ -152,8 +153,7 @@ int pager_open(PagerFlags flags) { + _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()) +@@ -164,6 +164,25 @@ int pager_open(PagerFlags flags) { + _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_args) { + r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false); + if (r < 0) { +-- +2.30.2 + diff --git a/debian/patches/0003-pager-Fix-deadlock-when-using-built-in-pager.patch b/debian/patches/0003-pager-Fix-deadlock-when-using-built-in-pager.patch new file mode 100644 index 0000000..ab5a229 --- /dev/null +++ b/debian/patches/0003-pager-Fix-deadlock-when-using-built-in-pager.patch @@ -0,0 +1,35 @@ +From d982f0decd1215d6fbd60c0e9ce6c0ffb8a0188c Mon Sep 17 00:00:00 2001 +From: Felix Riemann <felix.riemann@sma.de> +Date: Wed, 29 May 2019 21:17:42 +0200 +Subject: pager: Fix deadlock when using built-in pager + +The parent is waiting for an EOF on the pipe transmitting the pager name +before starting to send data. With external pagers this happens due to +execlp() CLOEXEC'ing the pipe, so the internal pager needs to close it +manually. +--- + src/shared/pager.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/shared/pager.c b/src/shared/pager.c +index 7a56271760..6f1d57a096 100644 +--- a/src/shared/pager.c ++++ b/src/shared/pager.c +@@ -212,11 +212,13 @@ int pager_open(PagerFlags flags) { + "Failed to execute '%s', using next fallback pager: %m", exe); + } + +- r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in") + 1, false); ++ r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in)") + 1, false); + if (r < 0) { + log_error_errno(r, "Failed to write pager name to socket: %m"); + _exit(EXIT_FAILURE); + } ++ /* Close pipe to signal the parent to start sending data */ ++ safe_close_pair(exe_name_pipe); + pager_fallback(); + /* not reached */ + } +-- +2.30.2 + diff --git a/debian/patches/0004-pager-make-pager-secure-when-under-euid-is-changed-o.patch b/debian/patches/0004-pager-make-pager-secure-when-under-euid-is-changed-o.patch new file mode 100644 index 0000000..6138f80 --- /dev/null +++ b/debian/patches/0004-pager-make-pager-secure-when-under-euid-is-changed-o.patch @@ -0,0 +1,180 @@ +From d8510d35c857547ddb601a988545ccb9a1e43fcc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Wed, 7 Oct 2020 11:15:05 +0200 +Subject: 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 +--- + man/less-variables.xml | 30 ++++++++++++++++---- + src/shared/pager.c | 63 ++++++++++++++++++++++++++++-------------- + 2 files changed, 66 insertions(+), 27 deletions(-) + +diff --git a/man/less-variables.xml b/man/less-variables.xml +index fed4178b01..b892854509 100644 +--- a/man/less-variables.xml ++++ b/man/less-variables.xml +@@ -61,12 +61,30 @@ + </varlistentry> + + <varlistentry id='lesssecure'> +- <term><varname>$SYSTEMD_LESSSECURE</varname></term> +- +- <listitem><para>Takes a boolean argument. Overrides the <varname>$LESSSECURE</varname> environment +- variable when invoking the pager, which controls the "secure" mode of less (which disables commands +- such as <literal>|</literal> which allow to easily shell out to external command lines). By default +- less secure mode is enabled, with this setting it may be disabled.</para></listitem> ++ <term><varname>$SYSTEMD_PAGERSECURE</varname></term> ++ ++ <listitem><para>Takes a boolean argument. When true, the "secure" mode of the pager is enabled; if ++ false, disabled. If <varname>$SYSTEMD_PAGERSECURE</varname> 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 <citerefentry ++ project='man-pages'><refentrytitle>geteuid</refentrytitle><manvolnum>2</manvolnum></citerefentry> and ++ <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>. ++ In secure mode, <option>LESSSECURE=1</option> will be set when invoking the pager, and the pager shall ++ disable commands that open or create new files or start new subprocesses. When ++ <varname>$SYSTEMD_PAGERSECURE</varname> is not set at all, pagers which are not known to implement ++ secure mode will not be used. (Currently only ++ <citerefentry><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> implements ++ secure mode.)</para> ++ ++ <para>Note: when commands are invoked with elevated privileges, for example under <citerefentry ++ project='man-pages'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry> or ++ <citerefentry ++ project='die-net'><refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>, 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 <varname>SYSTEMD_PAGERSECURE=0</varname> ++ or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note ++ that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to be ++ honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too. It might be reasonable to completly ++ disable the pager using <option>--no-pager</option> instead.</para></listitem> + </varlistentry> + + </variablelist> +diff --git a/src/shared/pager.c b/src/shared/pager.c +index 6f1d57a096..0f53cad429 100644 +--- a/src/shared/pager.c ++++ b/src/shared/pager.c +@@ -10,6 +10,8 @@ + #include <sys/prctl.h> + #include <unistd.h> + ++#include "sd-login.h" ++ + #include "copy.h" + #include "env-util.h" + #include "fd-util.h" +@@ -165,25 +167,42 @@ int pager_open(PagerFlags flags) { + } + + /* 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"); + +- if (setenv("LESSSECURE", "1", 1) < 0) { +- log_error_errno(errno, "Failed to set environment variable LESSSECURE: %m"); +- _exit(EXIT_FAILURE); +- } ++ 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 (pager_args) { ++ /* 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 (trust_pager && pager_args) { /* 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. */ + r = loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false); + if (r < 0) { + log_error_errno(r, "Failed to write pager name to socket: %m"); +@@ -195,13 +214,14 @@ int pager_open(PagerFlags flags) { + "Failed to execute '%s', using fallback pagers: %m", pager_args[0]); + } + +- /* 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. */ ++ /* 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; ++ + r = loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false); + if (r < 0) { + log_error_errno(r, "Failed to write pager name to socket: %m"); +@@ -212,6 +232,7 @@ int pager_open(PagerFlags flags) { + "Failed to execute '%s', using next fallback pager: %m", exe); + } + ++ /* Our builtin is also very secure. */ + r = loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in)") + 1, false); + if (r < 0) { + log_error_errno(r, "Failed to write pager name to socket: %m"); +-- +2.30.2 + diff --git a/debian/patches/series b/debian/patches/series index 3952047..e224247 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -77,3 +77,7 @@ debian/Revert-core-enable-TasksMax-for-all-services-by-default-a.patch debian/Let-graphical-session-pre.target-be-manually-started.patch debian/Add-env-variable-for-machine-ID-path.patch debian/Drop-seccomp-system-call-filter-for-udev.patch +0001-man-share-description-of-SYSTEMD_COLORS-in-other-too.patch +0002-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch +0003-pager-Fix-deadlock-when-using-built-in-pager.patch +0004-pager-make-pager-secure-when-under-euid-is-changed-o.patch |