]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
machined: add early checks for unrealistically large image/pool sizes
authorLennart Poettering <lennart@poettering.net>
Tue, 26 Jan 2016 18:02:12 +0000 (19:02 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 27 Jan 2016 01:21:28 +0000 (02:21 +0100)
src/basic/btrfs-util.c
src/basic/io-util.h
src/machine/image-dbus.c
src/machine/machined-dbus.c

index d07d1df5a8872d7d024dc849fa4b76cd4963d42b..03c7609c928edc66971ab04297ed10d8d24b482d 100644 (file)
@@ -43,6 +43,7 @@
 #include "copy.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "io-util.h"
 #include "macro.h"
 #include "missing.h"
 #include "path-util.h"
@@ -913,6 +914,10 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
         dev_t dev = 0;
         int r;
 
+        /* In contrast to btrfs quota ioctls ftruncate() cannot make sense of "infinity" or file sizes > 2^31 */
+        if (!FILE_SIZE_VALID(new_size))
+                return -EINVAL;
+
         /* btrfs cannot handle file systems < 16M, hence use this as minimum */
         if (new_size < 16*1024*1024)
                 new_size = 16*1024*1024;
index 5f77a556c047112ebffa183b7f573066a3686279..7d0d2bd810e7b37e13a7bf28375d9f3919c50e42 100644 (file)
@@ -77,3 +77,21 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
 
         return k;
 }
+
+static inline bool FILE_SIZE_VALID(uint64_t l) {
+        /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than
+         * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */
+
+        return (l >> 63) == 0;
+}
+
+static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) {
+
+        /* Same as above, but allows one extra value: -1 as indication for infinity. */
+
+        if (l == (uint64_t) -1)
+                return true;
+
+        return FILE_SIZE_VALID(l);
+
+}
index 4ec1766033906ba4b6be102ad1bd5cdc7c5ac88c..19388b016ad0be96942457d2ad45a88188065195 100644 (file)
@@ -23,6 +23,7 @@
 #include "bus-label.h"
 #include "bus-util.h"
 #include "image-dbus.h"
+#include "io-util.h"
 #include "machine-image.h"
 #include "strv.h"
 #include "user-util.h"
@@ -195,6 +196,8 @@ int bus_image_method_set_limit(
         r = sd_bus_message_read(message, "t", &limit);
         if (r < 0)
                 return r;
+        if (!FILE_SIZE_VALID_OR_INFINITY(limit))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
 
         r = bus_verify_polkit_async(
                         message,
index 521043f6a3b4b92bd70be83c6c9b94d58821e1f1..6cb70af3aaa4de0b36faeb8676544d425585975e 100644 (file)
@@ -34,6 +34,7 @@
 #include "formats-util.h"
 #include "hostname-util.h"
 #include "image-dbus.h"
+#include "io-util.h"
 #include "machine-dbus.h"
 #include "machine-image.h"
 #include "machine-pool.h"
@@ -813,6 +814,8 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
         r = sd_bus_message_read(message, "t", &limit);
         if (r < 0)
                 return r;
+        if (!FILE_SIZE_VALID_OR_INFINITY(limit))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
 
         r = bus_verify_polkit_async(
                         message,