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/journal/journald-native.c | |
parent | 08f9588885c5d65694b324846b0ed19211d2c178 (diff) |
journald: only accept fds from certain directories
Diffstat (limited to 'src/journal/journald-native.c')
-rw-r--r-- | src/journal/journald-native.c | 37 |
1 files changed, 34 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) { |