dissect-image: let's lock down fstypes a bit

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.
This commit is contained in:
Lennart Poettering 2022-12-21 10:00:06 +01:00 committed by Yu Watanabe
parent e20bae24d1
commit 80ce8580f5
4 changed files with 55 additions and 0 deletions

View 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

View 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);

View file

@ -74,6 +74,38 @@
/* 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");

View 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);