]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: let's lock down fstypes a bit
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Dec 2022 09:00:06 +0000 (10:00 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 22 Dec 2022 01:30:35 +0000 (10:30 +0900)
When we dissect images automatically, let's be a bit more conservative
with the file system types we are willing to mount: only mount common
file systems automatically.

Explicit mounts requested by admins should always be OK, but when we do
automatic mounts, let's not permit barely maintained, possibly legacy
file systems.

The list for now covers the four common writable and two common
read-only file systems. Sooner or later we might want to add more to the
list.

Also, it might make sense to eventually make this configurable via the
image dissection policy logic.

docs/ENVIRONMENT.md
src/gpt-auto-generator/gpt-auto-generator.c
src/shared/dissect-image.c
src/shared/dissect-image.h

index b4fa682cae8984359f0ebf3dbaaac0a06eba1d03..fb353004190fe6f004146bb47ee00a5f38a97a87 100644 (file)
@@ -415,6 +415,10 @@ disk images with `--image=` or similar:
 * `$SYSTEMD_DISSECT_VERITY_TIMEOUT_SEC=sec` — takes a timespan, which controls
   the timeout waiting for the image to be configured. Defaults to 100 msec.
 
+* `$SYSTEMD_DISSECT_FILE_SYSTEMS=` — takes a colon-separated list of file
+  systems that may be mounted for automatically dissected disk images. If not
+  specified defaults to something like: `ext4:btrfs:xfs:vfat:erofs:squashfs`
+
 * `$SYSTEMD_LOOP_DIRECT_IO` – takes a boolean, which controls whether to enable
   LO_FLAGS_DIRECT_IO (i.e. direct IO + asynchronous IO) on loopback block
   devices when opening them. Defaults to on, set this to "0" to disable this
index d697a9b362ca15737ccd345faa9ea5a7e2973e05..1d626f2a5a0ffa795bb43b948eb165b4281b6b11 100644 (file)
@@ -170,6 +170,15 @@ static int add_mount(
 
                 what = crypto_what;
                 fstype = NULL;
+        } else if (fstype) {
+                r = dissect_fstype_ok(fstype);
+                if (r < 0)
+                        return log_error_errno(r, "Unable to determine of dissected file system type '%s' is permitted: %m", fstype);
+                if (!r)
+                        return log_error_errno(
+                                        SYNTHETIC_ERRNO(EIDRM),
+                                        "Refusing to automatically mount uncommon file system '%s' to '%s'.",
+                                        fstype, where);
         }
 
         r = unit_name_from_path(where, ".mount", &unit);
index 4351f185cde6802d9ccb9b725e4e0e0f6359b08f..100b8cc8f147baccae30a32bbe550313efe3ef3a 100644 (file)
 /* how many times to wait for the device nodes to appear */
 #define N_DEVICE_NODE_LIST_ATTEMPTS 10
 
+int dissect_fstype_ok(const char *fstype) {
+        const char *e;
+        bool b;
+
+        /* When we automatically mount file systems, be a bit conservative by default what we are willing to
+         * mount, just as an extra safety net to not mount with badly maintained legacy file system
+         * drivers. */
+
+        e = secure_getenv("SYSTEMD_DISSECT_FILE_SYSTEMS");
+        if (e) {
+                _cleanup_strv_free_ char **l = NULL;
+
+                l = strv_split(e, ":");
+                if (!l)
+                        return -ENOMEM;
+
+                b = strv_contains(l, fstype);
+        } else
+                b = STR_IN_SET(fstype,
+                               "btrfs",
+                               "erofs",
+                               "ext4",
+                               "squashfs",
+                               "vfat",
+                               "xfs");
+        if (b)
+                return true;
+
+        log_debug("File system type '%s' is not allowed to be mounted as result of automatic dissection.", fstype);
+        return false;
+}
+
 int probe_filesystem_full(
                 int fd,
                 const char *path,
@@ -1339,6 +1371,11 @@ static int mount_partition(
 
         if (!fstype)
                 return -EAFNOSUPPORT;
+        r = dissect_fstype_ok(fstype);
+        if (r < 0)
+                return r;
+        if (!r)
+                return -EIDRM; /* Recognizable error */
 
         /* We are looking at an encrypted partition? This either means stacked encryption, or the caller
          * didn't call dissected_image_decrypt() beforehand. Let's return a recognizable error for this
@@ -1488,6 +1525,7 @@ int dissected_image_mount(
          *  -EUCLEAN      → fsck for file system failed
          *  -EBUSY        → File system already mounted/used elsewhere (kernel)
          *  -EAFNOSUPPORT → File system type not supported or not known
+         *  -EIDRM        → File system is not among allowlisted "common" file systems
          */
 
         if (!(m->partitions[PARTITION_ROOT].found ||
@@ -1625,6 +1663,8 @@ int dissected_image_mount_and_warn(
                 return log_error_errno(r, "File system already mounted elsewhere.");
         if (r == -EAFNOSUPPORT)
                 return log_error_errno(r, "File system type not supported or not known.");
+        if (r == -EIDRM)
+                return log_error_errno(r, "File system is too uncommon, refused.");
         if (r < 0)
                 return log_error_errno(r, "Failed to mount image: %m");
 
index 37a41e050a9b16a6c6b30aa6b63fe1ca67352b69..b65193f8872aa9df610bc482e6635a12b597a7d3 100644 (file)
@@ -183,3 +183,5 @@ bool dissected_image_verity_sig_ready(const DissectedImage *image, PartitionDesi
 int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device);
 
 int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, const MountOptions *options, const char *required_host_os_release_id, const char *required_host_os_release_version_id, const char *required_host_os_release_sysext_level, const char *required_sysext_scope);
+
+int dissect_fstype_ok(const char *fstype);