Blob Blame Raw
From eae11ffbcce26546b4c10634b30efd69908ea3fb Mon Sep 17 00:00:00 2001
From: Dave Love <dave.love@manchester.ac.uk>
Date: Mon, 15 May 2017 10:58:35 +0100
Subject: [PATCH 25/30] Drop privileges before printing messages Also staticize
 messagelevel, init.

---
 src/lib/message.c | 43 +++++++++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/src/lib/message.c b/src/lib/message.c
index 1036b052..6f2a9cfe 100644
--- a/src/lib/message.c
+++ b/src/lib/message.c
@@ -31,13 +31,14 @@
 
 #include "util/util.h"
 #include "lib/message.h"
+#include "lib/privilege.h"
 
-int messagelevel = -1;
+static int messagelevel = -1;
 
 extern const char *__progname;
 
-void init(void) {
-    char *messagelevel_string = getenv("MESSAGELEVEL"); // Flawfinder: ignore (need to get string, validation in atol())
+static void init(void) {
+    char *messagelevel_string = envar("MESSAGELEVEL", "", 4);
     char **endptr = &messagelevel_string;
     long l;
 
@@ -68,6 +69,15 @@ void _singularity_message(int level, const char *function, const char *file, int
     char message[512]; // Flawfinder: ignore (messages are truncated to 512 chars)
     char *prefix = "";
     va_list args;
+    static unsigned recur = 0;
+    int privileged = geteuid() == 0;
+
+    /* Recursive calls via the privilege-dropping below could cause
+     * trouble with error conditions.  The best we can do is to avoid
+     * recursive messages.  */
+    if (recur > 0) return;
+    recur++;
+
     va_start (args, format);
 
     vsnprintf(message, 512, format, args); // Flawfinder: ignore (format is internally defined)
@@ -120,19 +130,23 @@ void _singularity_message(int level, const char *function, const char *file, int
             char debug_string[25];
             char location_string[60];
             char tmp_header_string[86];
-            snprintf(location_string, 60, "%s:%d:%s()", file, line, function); // Flawfinder: ignore
-            location_string[59] = '\0';
-            snprintf(debug_string, 25, "[U=%d,P=%d]", geteuid(), getpid()); // Flawfinder: ignore
-            debug_string[24] = '\0';
-            snprintf(tmp_header_string, 86, "%-18s %s", debug_string, location_string); // Flawfinder: ignore
-            tmp_header_string[85] = '\0';
-            snprintf(header_string, 95, "%-7s %-62s: ", prefix, tmp_header_string); // Flawfinder: ignore
-            header_string[94] = '\0';
+            snprintf(location_string, sizeof location_string, "%s:%d:%s()", file, line, function); // Flawfinder: ignore
+            snprintf(debug_string, sizeof debug_string, "[U=%d,P=%d]", geteuid(), getpid()); // Flawfinder: ignore
+            snprintf(tmp_header_string, sizeof tmp_header_string, "%-18s %s", debug_string, location_string); // Flawfinder: ignore
+            snprintf(header_string, sizeof header_string, "%-7s %-62s: ", prefix, tmp_header_string); // Flawfinder: ignore
         } else {
-            snprintf(header_string, 10, "%-7s: ", prefix); // Flawfinder: ignore
-            header_string[9] = '\0';
+            snprintf(header_string, sizeof header_string, "%-7s: ", prefix); // Flawfinder: ignore
         }
 
+        /* Don't print messages when privileged.  They may have
+         * user-controlled contents from arguments or the environment,
+         * with the possibility of injecting input via terminal
+         * control sequences to which the terminal responds with an
+         * escape sequence.  Cleaning escape characters as an
+         * alternative might fall foul of iso-2022 etc. in the absence
+         * of m17n support.  */
+        if (privileged) singularity_priv_drop();
+
         if ( level == INFO && messagelevel == INFO ) {
             printf("%s", message);
         } else if ( level == INFO ) {
@@ -143,9 +157,10 @@ void _singularity_message(int level, const char *function, const char *file, int
             fprintf(stderr, "%s", strjoin(header_string, message));
         }
 
+        if (privileged) singularity_priv_escalate();
         fflush(stdout);
         fflush(stderr);
 
     }
-
+    recur--;
 }
-- 
2.11.0