X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournald-native.c;h=de8d6998cfdc0c7a35d381041d7d308be72ef802;hb=0ce8860a15fb08ac358fb9c5347bd20c0bcdebcd;hp=4e44c3ada78c4d16c05ba38f12ff6a54c749b603;hpb=4871690d9e32608bbd9b18505b5326c2079c9690;p=elogind.git diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c index 4e44c3ada..de8d6998c 100644 --- a/src/journal/journald-native.c +++ b/src/journal/journald-native.c @@ -24,13 +24,15 @@ #include #include "socket-util.h" +#include "path-util.h" #include "journald.h" #include "journald-native.h" #include "journald-kmsg.h" #include "journald-console.h" #include "journald-syslog.h" -#define ENTRY_SIZE_MAX (1024*1024*32) +#define ENTRY_SIZE_MAX (1024*1024*64) +#define DATA_SIZE_MAX (1024*1024*64) static bool valid_user_field(const char *p, size_t l) { const char *a; @@ -205,7 +207,12 @@ void server_process_native_message( memcpy(&l_le, e + 1, sizeof(uint64_t)); l = le64toh(l_le); - if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || + if (l > DATA_SIZE_MAX) { + log_debug("Received binary data block too large, ignoring."); + break; + } + + if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || e[1+sizeof(uint64_t)+l] != '\n') { log_debug("Failed to parse message, ignoring."); break; @@ -275,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 (!filename_is_safe(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 @@ -315,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) {