mke2fs: disallow creating FS on a loop mounted file with no option

When /etc/mtab is a symlink of /proc/mounts, mke2fs without -FF option
can create a filesystem on the image file that is mounted.
According to mke2fs man page, we should specify -FF option in this case.

This patch protects filesystem from unintended mke2fs caused by human error.

How to reproduce:
  # mke2fs -t ext4 -Fq fs.img
  # mount -o loop fs.img /mnt/mp1
  # mke2fs -t ext4 -Fq fs.img && echo "mke2fs success"
  mke2fs success

Signed-off-by: Kazuya Mio <k-mio@sx.jp.nec.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
debian-1.42.9
Kazuya Mio 2013-12-16 00:48:12 -05:00 committed by Theodore Ts'o
parent 82896cbe0e
commit fbabd5c44c
3 changed files with 43 additions and 1 deletions

2
configure vendored
View File

@ -10370,7 +10370,7 @@ fi
done
fi
for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h linux/falloc.h linux/fd.h linux/major.h net/if_dl.h netinet/in.h sys/disklabel.h sys/file.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/prctl.h sys/queue.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h
for ac_header in dirent.h errno.h execinfo.h getopt.h malloc.h mntent.h paths.h semaphore.h setjmp.h signal.h stdarg.h stdint.h stdlib.h termios.h termio.h unistd.h utime.h linux/falloc.h linux/fd.h linux/major.h linux/loop.h net/if_dl.h netinet/in.h sys/disklabel.h sys/file.h sys/ioctl.h sys/mkdev.h sys/mman.h sys/prctl.h sys/queue.h sys/resource.h sys/select.h sys/socket.h sys/sockio.h sys/stat.h sys/syscall.h sys/sysmacros.h sys/time.h sys/types.h sys/un.h sys/wait.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

View File

@ -866,6 +866,7 @@ AC_CHECK_HEADERS(m4_flatten([
linux/falloc.h
linux/fd.h
linux/major.h
linux/loop.h
net/if_dl.h
netinet/in.h
sys/disklabel.h

View File

@ -21,6 +21,13 @@
#ifdef HAVE_LINUX_FD_H
#include <linux/fd.h>
#endif
#ifdef HAVE_LINUX_LOOP_H
#include <linux/loop.h>
#include <sys/ioctl.h>
#ifdef HAVE_LINUX_MAJOR_H
#include <linux/major.h>
#endif /* HAVE_LINUX_MAJOR_H */
#endif /* HAVE_LINUX_LOOP_H */
#ifdef HAVE_MNTENT_H
#include <mntent.h>
#endif
@ -35,6 +42,36 @@
#include "ext2_fs.h"
#include "ext2fs.h"
/*
* Check to see if a regular file is mounted.
* If /etc/mtab/ is a symlink of /proc/mounts, you will need the following check
* because the name in /proc/mounts is a loopback device not a regular file.
*/
static int check_loop_mounted(const char *mnt_fsname, dev_t mnt_rdev,
dev_t file_dev, ino_t file_ino)
{
#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H)
struct loop_info64 loopinfo;
int loop_fd, ret;
if (major(mnt_rdev) == LOOP_MAJOR) {
loop_fd = open(mnt_fsname, O_RDONLY);
if (loop_fd < 0)
return -1;
ret = ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo);
close(loop_fd);
if (ret < 0)
return -1;
if (file_dev == loopinfo.lo_device &&
file_ino == loopinfo.lo_inode)
return 1;
}
#endif /* defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) */
return 0;
}
#ifdef HAVE_SETMNTENT
/*
* Helper function which checks a file in /etc/mtab format to see if a
@ -82,6 +119,10 @@ static errcode_t check_mntent_file(const char *mtab_file, const char *file,
#ifndef __GNU__
if (file_rdev && (file_rdev == st_buf.st_rdev))
break;
if (check_loop_mounted(mnt->mnt_fsname,
st_buf.st_rdev, file_dev,
file_ino) == 1)
break;
#endif /* __GNU__ */
} else {
if (file_dev && ((file_dev == st_buf.st_dev) &&