pager: set $LESSSECURE whenver we invoke a pager
authorLennart Poettering <lennart@poettering.net>
Mon, 31 Aug 2020 17:37:13 +0000 (19:37 +0200)
committerAdrian Bunk <bunk@debian.org>
Thu, 29 Jun 2023 13:57:02 +0000 (14:57 +0100)
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

Gbp-Pq: Name 0002-pager-set-LESSSECURE-whenver-we-invoke-a-pager.patch

man/less-variables.xml
man/systemctl.xml
man/systemd.xml
src/shared/pager.c

index 334eb198715fdf1056e7bc2f56772be311defaf5..fed4178b010af60f436d756da9ab4fb21aaa362e 100644 (file)
       </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>
index 08aacd8f41c9ae7e9e7628ffd741d55ffc5aa768..22b26d36072d1cd94cdc99ecff3df098401e60ae 100644 (file)
@@ -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>
index 1ff1f34dbeb7fb619ebb5ce4d3fb7246c02b2a11..d0d847c353c61b47275242461e067225f2793ceb 100644 (file)
 
       <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>
index bf2597e65a12585ce398522b29a89d404d921fea..7a56271760ad916a27bdbb03c9489aaa1d38a397 100644 (file)
@@ -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) {