Patchwork [2/2,V2] mke2fs: disallow creating FS on a loop mounted file with no option

login
register
mail settings
Submitter Kazuya Mio
Date June 24, 2013, 6:29 a.m.
Message ID <51C7E733.8090003@sx.jp.nec.com>
Download mbox | patch
Permalink /patch/253633/
State Superseded
Headers show

Comments

Kazuya Mio - June 24, 2013, 6:29 a.m.
When /etc/mtab is a symlink of /proc/mounts, mke2fs can create a filesystem
on the loop mounted file without -F option. In this case, we should specify
-F option twice.

How to reproduce:
  # mke2fs -t ext4 -Fq /mnt/mp1/fs.img
  # mount -o loop /mnt/mp1/fs.img /mnt/mp2
  # mke2fs -t ext4 -q /mnt/mp1/fs.img
  /mnt/mp1/fs.img is not a block special device.
  Proceed anyway? (y,n) y
  # echo $?
  0

Signed-off-by: Kazuya Mio <k-mio@sx.jp..nec.com>
---
 configure.in           |    2 ++
 lib/ext2fs/ismounted.c |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/configure.in b/configure.in
index 8963d17..fe29aa3 100644
--- a/configure.in
+++ b/configure.in
@@ -912,6 +912,8 @@  AC_CHECK_HEADERS(m4_flatten([
 	linux/falloc.h
 	linux/fd.h
 	linux/major.h
+	linux/version.h
+	linux/loop.h
 	net/if_dl.h
 	netinet/in.h
 	sys/disklabel.h
diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
index 6a223df..499b4c0 100644
--- a/lib/ext2fs/ismounted.c
+++ b/lib/ext2fs/ismounted.c
@@ -21,6 +21,14 @@ 
 #ifdef HAVE_LINUX_FD_H
 #include <linux/fd.h>
 #endif
+#ifdef HAVE_LINUX_VERSION_H
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) /* kernel >= 2.6 */
+#ifdef HAVE_LINUX_LOOP_H
+#include <linux/loop.h>
+#endif /* HAVE_LINUX_LOOP_H */
+#endif /* kernel >= 2.6 */
+#endif /* HAVE_LINUX_VERSION_H */
 #ifdef HAVE_MNTENT_H
 #include <mntent.h>
 #endif
@@ -31,6 +39,7 @@ 
 #endif /* HAVE_GETMNTINFO */
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 
 #include "ext2_fs.h"
 #include "ext2fs.h"
@@ -51,6 +60,11 @@  static errcode_t check_mntent_file(const char *mtab_file, const char *file,
 	ino_t		file_ino=0;
 	FILE 		*f;
 	int		fd;
+#if defined(HAVE_LINUX_LOOP_H) && defined(LOOP_GET_STATUS64)
+	int		result = 0;
+	struct loop_info64 lo_info;
+	memset(&lo_info, 0, sizeof(struct loop_info64));
+#endif /* defined(HAVE_LINUX_LOOP_H) && defined(LOOP_GET_STATUS64) */
 
 	*mount_flags = 0;
 	if ((f = setmntent (mtab_file, "r")) == NULL)
@@ -70,6 +84,30 @@  static errcode_t check_mntent_file(const char *mtab_file, const char *file,
 			continue;
 		if (strcmp(file, mnt->mnt_fsname) == 0)
 			break;
+#if defined(HAVE_LINUX_LOOP_H) && defined(LOOP_GET_STATUS64)
+		/*
+		 * 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.
+		 */
+		if (strncmp(mnt->mnt_fsname, "/dev/loop", 9) == 0) {
+			fd = open(mnt->mnt_fsname, O_RDONLY);
+			if (fd < 0) {
+				retval = errno;
+				goto errout;
+			}
+			result = ioctl(fd, LOOP_GET_STATUS64, &lo_info);
+			close(fd);
+			if (result < 0) {
+				retval = errno;
+				goto errout;
+			}
+			if (file_dev == lo_info.lo_device &&
+				file_ino == lo_info.lo_inode)
+				break;
+		}
+#endif /* defined(HAVE_LINUX_LOOP_H) && defined(LOOP_GET_STATUS64) */
 		if (stat(mnt->mnt_fsname, &st_buf) == 0) {
 			if (S_ISBLK(st_buf.st_mode)) {
 #ifndef __GNU__