From: zhanchengbin Date: Tue, 4 Jan 2022 14:23:52 +0000 (+0800) Subject: libext2fs: add extra checks to ext2fs_check_mount_point() X-Git-Tag: v1.46.6~98 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4d2dcb56d276aff8ed0a730152dcbeda32257da8;p=tools%2Fe2fsprogs.git libext2fs: add extra checks to ext2fs_check_mount_point() A pseudo-filesystem, such as tmpfs, can have anything at all in its mnt_fsname entry. Normally, it is just "tmpfs", like this: tmpfs /tmp tmpfs rw,relatime,inode64 0 0 ^^^^^ but in a pathological or malicious case, a system administrator can specify a block device as its mnt_fsname which is the same as some other block device. For example: /dev/loop0 /tmp/test-tmpfs tmpfs rw,relatime,inode64 0 0 ^^^^^^^^^^ /dev/loop0 /tmp/test-mnt ext4 rw,relatime 0 0 In this case, ext2fs_check_mount_point() may erroneously return that the mountpoint for the file system on /dev/loop0 is mounted on /tmp/test-tmpfs, instead of the correct /tmp/test-mnt. This causes problems for resize2fs, since in order to do an online resize, it needs to open the directory where the file system is mounted, and trigger the online resize ioctl. If it opens the incorrect directory, then resize2fs will fail. So we need to add some additional checking to make sure that directory's st_dev matches the block device's st_rdev field. An example shell script which reproduces the problem fixed by this commit is as follows: loop_file=/tmp/foo.img tmpfs_dir=/tmp/test-tmpfs mnt_dir=/tmp/test-mnt mkdir -p $tmpfs_dir $mnt_dir dd if=/dev/zero of=$loop_file bs=1k count=65536 test_dev=$(losetup --show -f $loop_file) mke2fs -t ext4 -F -b 1024 $test_dev 32768 mount -t tmpfs $test_dev $tmpfs_dir # create the evil /proc/mounts entry mount -t ext4 $test_dev $mnt_dir ln -f ${test_dev} ${test_dev}-ln resize2fs ${test_dev}-ln [ Fixed up the corrupted patch and rewrote the commit description to be more clear -- tytso ] Signed-off-by: zhanchengbin Signed-off-by: Zhiqiang Liu Signed-off-by: Theodore Ts'o --- diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c index aee7d72..fe64e8b 100644 --- a/lib/ext2fs/ismounted.c +++ b/lib/ext2fs/ismounted.c @@ -97,7 +97,7 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file, int *mount_flags, char *mtpt, int mtlen) { struct mntent *mnt; - struct stat st_buf; + struct stat st_buf, dir_st_buf; errcode_t retval = 0; dev_t file_dev=0, file_rdev=0; ino_t file_ino=0; @@ -144,8 +144,14 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file, if (stat(mnt->mnt_fsname, &st_buf) == 0) { if (ext2fsP_is_disk_device(st_buf.st_mode)) { #ifndef __GNU__ - if (file_rdev && (file_rdev == st_buf.st_rdev)) - break; + if (file_rdev && + (file_rdev == st_buf.st_rdev)) { + if (stat(mnt->mnt_dir, + &dir_st_buf) != 0) + continue; + if (file_rdev == dir_st_buf.st_dev) + break; + } if (check_loop_mounted(mnt->mnt_fsname, st_buf.st_rdev, file_dev, file_ino) == 1)