]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: never accept fds from file systems with mandatory locking enabled
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 19:08:04 +0000 (20:08 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 20:03:49 +0000 (21:03 +0100)
This is pretty much a work-around for a security vulnerability in
kernels that allow unprivileged user namespaces.

Fixes #1822.

src/journal/journald-native.c

index 1e3774dafb6eed4f5cbfe12b5e5df26fac07b510..69a685c06f26201139049ff9c295375595de6722 100644 (file)
@@ -22,6 +22,7 @@
 #include <stddef.h>
 #include <sys/epoll.h>
 #include <sys/mman.h>
+#include <sys/statvfs.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
@@ -399,8 +400,37 @@ void server_process_native_file(
                 assert_se(munmap(p, ps) >= 0);
         } else {
                 _cleanup_free_ void *p = NULL;
+                struct statvfs vfs;
                 ssize_t n;
 
+                if (fstatvfs(fd, &vfs) < 0) {
+                        log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m");
+                        return;
+                }
+
+                /* Refuse operating on file systems that have
+                 * mandatory locking enabled, see:
+                 *
+                 * https://github.com/systemd/systemd/issues/1822
+                 */
+                if (vfs.f_flag & ST_MANDLOCK) {
+                        log_error("Received file descriptor from file system with mandatory locking enable, refusing.");
+                        return;
+                }
+
+                /* Make the fd non-blocking. On regular files this has
+                 * the effect of bypassing mandatory locking. Of
+                 * course, this should normally not be necessary given
+                 * the check above, but let's better be safe than
+                 * sorry, after all NFS is pretty confusing regarding
+                 * file system flags, and we better don't trust it,
+                 * and so is SMB. */
+                r = fd_nonblock(fd, true);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m");
+                        return;
+                }
+
                 /* The file is not sealed, we can't map the file here, since
                  * clients might then truncate it and trigger a SIGBUS for
                  * us. So let's stupidly read it */