chiark / gitweb /
journald: only accept fds from certain directories
authorLennart Poettering <lennart@poettering.net>
Wed, 3 Oct 2012 15:37:44 +0000 (11:37 -0400)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Oct 2012 15:55:38 +0000 (11:55 -0400)
src/journal/journald-native.c
src/journal/test-journal-send.c

index 85458b50c29ccc94a8046fd9eec6ffab08595f33..12fb980dd6c5312df7c8875332ae3d05f0003c69 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/epoll.h>
 
 #include "socket-util.h"
 #include <sys/epoll.h>
 
 #include "socket-util.h"
+#include "path-util.h"
 #include "journald.h"
 #include "journald-native.h"
 #include "journald-kmsg.h"
 #include "journald.h"
 #include "journald-native.h"
 #include "journald-kmsg.h"
@@ -281,12 +282,44 @@ void server_process_native_file(
                 const char *label, size_t label_len) {
 
         struct stat st;
                 const char *label, size_t label_len) {
 
         struct stat st;
-        void *p;
+        _cleanup_free_ void *p = NULL;
         ssize_t n;
         ssize_t n;
+        int r;
 
         assert(s);
         assert(fd >= 0);
 
 
         assert(s);
         assert(fd >= 0);
 
+        if (!ucred || ucred->uid != 0) {
+                _cleanup_free_ char *sl = NULL, *k = NULL;
+                const char *e;
+
+                if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
+                        log_oom();
+                        return;
+                }
+
+                r = readlink_malloc(sl, &k);
+                if (r < 0) {
+                        log_error("readlink(%s) failed: %m", sl);
+                        return;
+                }
+
+                e = path_startswith(k, "/dev/shm/");
+                if (!e)
+                        e = path_startswith(k, "/tmp/");
+                if (!e)
+                        e = path_startswith(k, "/var/tmp/");
+                if (!e) {
+                        log_error("Received file outside of allowed directories. Refusing.");
+                        return;
+                }
+
+                if (strchr(e, '/')) {
+                        log_error("Received file in subdirectory of allowed directories. Refusing.");
+                        return;
+                }
+        }
+
         /* Data is in the passed file, since it didn't fit in a
          * datagram. We can't map the file here, since clients might
          * then truncate it and trigger a SIGBUS for us. So let's
         /* Data is in the passed file, since it didn't fit in a
          * datagram. We can't map the file here, since clients might
          * then truncate it and trigger a SIGBUS for us. So let's
@@ -321,8 +354,6 @@ void server_process_native_file(
                 log_error("Failed to read file, ignoring: %s", strerror(-n));
         else if (n > 0)
                 server_process_native_message(s, p, n, ucred, tv, label, label_len);
                 log_error("Failed to read file, ignoring: %s", strerror(-n));
         else if (n > 0)
                 server_process_native_message(s, p, n, ucred, tv, label, label_len);
-
-        free(p);
 }
 
 int server_open_native_socket(Server*s) {
 }
 
 int server_open_native_socket(Server*s) {
index e708fa440650d76d1e3e219efe024bddf6229751..168c84365b7d334e29ac545ff09630245df3ae8b 100644 (file)
@@ -24,6 +24,8 @@
 #include "log.h"
 
 int main(int argc, char *argv[]) {
 #include "log.h"
 
 int main(int argc, char *argv[]) {
+        char huge[4096*1024];
+
         log_set_max_level(LOG_DEBUG);
 
         sd_journal_print(LOG_INFO, "piepapo");
         log_set_max_level(LOG_DEBUG);
 
         sd_journal_print(LOG_INFO, "piepapo");
@@ -37,5 +39,13 @@ int main(int argc, char *argv[]) {
 
         sd_journal_perror("");
 
 
         sd_journal_perror("");
 
+        memset(huge, 'x', sizeof(huge));
+        memcpy(huge, "HUGE=", 5);
+        char_array_0(huge);
+
+        sd_journal_send("MESSAGE=Huge field attached",
+                        huge,
+                        NULL);
+
         return 0;
 }
         return 0;
 }