From 38d81fc89f325801922971229a894038fe207eae Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 24 May 2023 07:04:06 +0900 Subject: [PATCH] fstab-generator: refuse invalid mount point path in fstab earlier (cherry picked from commit 6742eca13497dd9dd548ba3e2ced2588d82720ac) Related: #2190226 --- src/fstab-generator/fstab-generator.c | 68 +++++++++++++-------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 2cd4de29f0..bd1508bc30 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -689,7 +689,7 @@ static int parse_fstab_one( int passno, bool initrd) { - _cleanup_free_ char *what = NULL, *where = NULL, *canonical_where = NULL; + _cleanup_free_ char *what = NULL, *where = NULL; MountPointFlags flags; bool is_swap; int r; @@ -725,50 +725,50 @@ static int parse_fstab_one( assert(where_original); /* 'where' is not necessary for swap entry. */ - where = strdup(where_original); - if (!where) - return log_oom(); - - if (is_path(where)) { - path_simplify(where); + if (!is_path(where_original)) { + log_warning("Mount point %s is not a valid path, ignoring.", where); + return 0; + } - /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for - * mount units, but causes problems since it historically worked to have symlinks in e.g. - * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case - * where a symlink refers to another mount target; this works assuming the sub-mountpoint - * target is the final directory. - * - * FIXME: when chase() learns to chase non-existent paths, use this here and - * drop the prefixing with /sysroot on error below. - */ - r = chase_symlinks(where, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, - &canonical_where, NULL); - if (r < 0) { - /* If we can't canonicalize, continue as if it wasn't a symlink */ - log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where); - - if (initrd) { - canonical_where = path_join("/sysroot", where); - if (!canonical_where) - return log_oom(); - } + /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for + * mount units, but causes problems since it historically worked to have symlinks in e.g. + * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case + * where a symlink refers to another mount target; this works assuming the sub-mountpoint + * target is the final directory. + * + * FIXME: when chase() learns to chase non-existent paths, use this here and + * drop the prefixing with /sysroot on error below. + */ + r = chase_symlinks(where_original, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &where, NULL); + if (r < 0) { + /* If we can't canonicalize, continue as if it wasn't a symlink */ + log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where_original); - } else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */ - canonical_where = mfree(canonical_where); + if (initrd) + where = path_join("/sysroot", where_original); else - log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where); + where = strdup(where_original); + if (!where) + return log_oom(); + + path_simplify(where); } + if (streq(where, where_original)) /* If it was fully canonicalized, suppress the change */ + where = mfree(where); + else + log_debug("Canonicalized what=%s where=%s to %s", what, where_original, where); + log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s", what, where, strna(fstype), yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS), yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL)); - bool is_sysroot = in_initrd() && path_equal(where, "/sysroot"); + bool is_sysroot = in_initrd() && path_equal(where ?: where_original, "/sysroot"); /* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs * to be mounted in order for the root fs to be synthesized based on configuration included in /usr/, * e.g. systemd-repart. */ - bool is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr"); + bool is_sysroot_usr = in_initrd() && path_equal(where ?: where_original, "/sysroot/usr"); const char *target_unit = initrd ? SPECIAL_INITRD_FS_TARGET : @@ -786,8 +786,8 @@ static int parse_fstab_one( r = add_mount(source, arg_dest, what, - is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where, - !is_sysroot_usr && canonical_where ? where : NULL, + is_sysroot_usr ? "/sysusr/usr" : where ?: where_original, + !is_sysroot_usr && where ? where_original : NULL, fstype, options, passno,