diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-10-03 11:37:44 -0400 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-10-03 11:55:38 -0400 |
commit | 1dfa7e79a60de680086b1d93fcc3629b463f58bd (patch) | |
tree | 288401e1a12f4bf633ae7725e7cb0d09201768e2 /src | |
parent | 08f9588885c5d65694b324846b0ed19211d2c178 (diff) |
journald: only accept fds from certain directories
Diffstat (limited to 'src')
-rw-r--r-- | src/journal/journald-native.c | 37 | ||||
-rw-r--r-- | src/journal/test-journal-send.c | 10 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 85458b50c2..12fb980dd6 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -24,6 +24,7 @@ #include <sys/epoll.h> #include "socket-util.h" +#include "path-util.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; - void *p; + _cleanup_free_ void *p = NULL; ssize_t n; + int r; 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 @@ -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); - - free(p); } int server_open_native_socket(Server*s) { diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c index e708fa4406..168c84365b 100644 --- a/src/journal/test-journal-send.c +++ b/src/journal/test-journal-send.c @@ -24,6 +24,8 @@ #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"); @@ -37,5 +39,13 @@ int main(int argc, char *argv[]) { 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; } |