aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzhanchengbin <zhanchengbin1@huawei.com>2022-01-04 22:23:52 +0800
committerTheodore Ts'o <tytso@mit.edu>2023-01-17 23:55:18 -0500
commit4d2dcb56d276aff8ed0a730152dcbeda32257da8 (patch)
tree8b647bc380d546150953ca10923aa382a231c1df
parent6695555e50a374f897965300568253f242a0b13b (diff)
downloade2fsprogs-4d2dcb56d276aff8ed0a730152dcbeda32257da8.tar.gz
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 <zhanchengbin1@huawei.com> Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--lib/ext2fs/ismounted.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
index aee7d7269..fe64e8bb3 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)