/* 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) {
+static int allowed_fstypes(char ***ret_strv) {
+ _cleanup_strv_free_ char **l = NULL;
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. */
+ assert(ret_strv);
e = secure_getenv("SYSTEMD_DISSECT_FILE_SYSTEMS");
if (e) {
- _cleanup_strv_free_ char **l = NULL;
-
l = strv_split(e, ":");
if (!l)
return -ENOMEM;
+ } else {
+ l = strv_new("btrfs",
+ "erofs",
+ "ext4",
+ "f2fs",
+ "squashfs",
+ "vfat",
+ "xfs");
+ if (!l)
+ return -ENOMEM;
+ }
- b = strv_contains(l, fstype);
- } else
- b = STR_IN_SET(fstype,
- "btrfs",
- "erofs",
- "ext4",
- "f2fs",
- "squashfs",
- "vfat",
- "xfs");
- if (b)
+ *ret_strv = TAKE_PTR(l);
+
+ return 0;
+}
+
+int dissect_fstype_ok(const char *fstype) {
+ _cleanup_strv_free_ char **l = NULL;
+ int r;
+
+ /* 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. */
+
+ r = allowed_fstypes(&l);
+ if (r < 0)
+ return r;
+
+ if (strv_contains(l, fstype))
return true;
log_debug("File system type '%s' is not allowed to be mounted as result of automatic dissection.", fstype);
return probe_sector_size(fd, ret);
}
+#if HAVE_BLKID
+static int probe_blkid_filter(blkid_probe p) {
+ _cleanup_strv_free_ char **fstypes = NULL;
+ int r;
+
+ assert(p);
+
+ r = allowed_fstypes(&fstypes);
+ if (r < 0)
+ return r;
+
+ errno = 0;
+ r = blkid_probe_filter_superblocks_type(p, BLKID_FLTR_ONLYIN, fstypes);
+ if (r != 0)
+ return errno_or_else(EINVAL);
+
+ errno = 0;
+ r = blkid_probe_filter_superblocks_usage(p, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
+ if (r != 0)
+ return errno_or_else(EINVAL);
+
+ return 0;
+}
+#endif
+
int probe_filesystem_full(
int fd,
const char *path,
uint64_t offset,
uint64_t size,
+ bool restrict_fstypes,
char **ret_fstype) {
/* Try to find device content type and return it in *ret_fstype. If nothing is found,
if (!b)
return -ENOMEM;
+ if (restrict_fstypes) {
+ r = probe_blkid_filter(b);
+ if (r < 0)
+ return r;
+ }
+
/* The Linux kernel maintains separate block device caches for main ("whole") and partition block
* devices, which means making a change to one might not be reflected immediately when reading via
* the other. That's massively confusing when mixing accesses to such devices. Let's address this in
/* If we have an fd referring to the partition block device, use that. Otherwise go
* via the whole block device or backing regular file, and read via offset. */
if (p->mount_node_fd >= 0)
- r = probe_filesystem_full(p->mount_node_fd, p->node, 0, UINT64_MAX, &p->fstype);
+ r = probe_filesystem_full(p->mount_node_fd, p->node, 0, UINT64_MAX, /* bool restrict_fstypes= */ true, &p->fstype);
else
- r = probe_filesystem_full(fd, p->node, p->offset, p->size, &p->fstype);
+ r = probe_filesystem_full(fd, p->node, p->offset, p->size, /* bool restrict_fstypes= */ true, &p->fstype);
if (r < 0)
return r;
}
if (!b)
return -ENOMEM;
+ r = probe_blkid_filter(b);
+ if (r < 0)
+ return r;
+
errno = 0;
r = blkid_probe_set_device(b, fd, 0, 0);
if (r != 0)
}
if (!p->decrypted_fstype && p->mount_node_fd >= 0 && p->decrypted_node) {
- r = probe_filesystem_full(p->mount_node_fd, p->decrypted_node, 0, UINT64_MAX, &p->decrypted_fstype);
+ r = probe_filesystem_full(p->mount_node_fd, p->decrypted_node, 0, UINT64_MAX, /* bool restrict_fstypes= */ true, &p->decrypted_fstype);
if (r < 0 && r != -EUCLEAN)
return r;
}
DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
-int probe_filesystem_full(int fd, const char *path, uint64_t offset, uint64_t size, char **ret_fstype);
+int probe_filesystem_full(int fd, const char *path, uint64_t offset, uint64_t size, bool restrict_fstypes, char **ret_fstype);
static inline int probe_filesystem(const char *path, char **ret_fstype) {
- return probe_filesystem_full(-1, path, 0, UINT64_MAX, ret_fstype);
+ return probe_filesystem_full(-1, path, 0, UINT64_MAX, /* bool restrict_fstypes= */ false, ret_fstype);
}
int dissect_log_error(int log_level, int r, const char *name, const VeritySettings *verity);