summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2009-11-19 15:56:12 +0100
committerKarel Zak2009-11-19 15:56:12 +0100
commitb7ce600d3d238ca3e82aa04ee6845afc45fb5eb8 (patch)
tree51dfc1626d479471b02f8b018d1e8f2619bd140c
parentionice: add a note about none class and CFQ (diff)
downloadkernel-qcow2-util-linux-b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8.tar.gz
kernel-qcow2-util-linux-b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8.tar.xz
kernel-qcow2-util-linux-b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8.zip
mount: check for unsuccessful read-only bind mounts
Linux kernel allows to use MS_RDONLY together with MS_BIND, unfortunately the MS_RDONLY is silently ignored and the target mountpoint is still read-write. Then we have 'ro' in mtab and 'rw' in /proc/mounts. This patch checks for this situation by access(2) or futimens(2) (change atime) and mtab is properly updated and user informed. Reported-by: Terry Burton <tez@terryburton.co.uk> Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--configure.ac1
-rw-r--r--mount/mount.c46
2 files changed, 47 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index fc0b9e1b8..d0356fdb3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,7 @@ AC_CHECK_DECLS([_NL_TIME_WEEK_1STDAY],[],[],[[#include <langinfo.h>]])
AC_CHECK_FUNCS(
[inet_aton \
+ futimens \
fsync \
getdomainname \
get_current_dir_name \
diff --git a/mount/mount.c b/mount/mount.c
index 23d70cb14..3eafa92ac 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -1226,6 +1226,41 @@ cdrom_setspeed(const char *spec) {
}
/*
+ * Check if @node is read-only filesystem by access() or futimens().
+ *
+ * Note that access(2) uses real-UID (= useless for suid programs)
+ * and euidaccess(2) does not check for read-only FS.
+ */
+static int
+is_readonly(const char *node)
+{
+ int res = 0;
+
+ if (getuid() == geteuid()) {
+ if (access(node, W_OK) == -1 && errno == EROFS)
+ res = 1;
+ }
+#ifdef HAVE_FUTIMENS
+ else {
+ struct timespec times[2];
+ int fd = open(node, O_RDONLY);
+
+ if (fd < 0)
+ goto done;
+
+ times[0].tv_nsec = UTIME_NOW; /* atime */
+ times[1].tv_nsec = UTIME_OMIT; /* mtime */
+
+ if (futimens(fd, times) == -1 && errno == EROFS)
+ res = 1;
+ close(fd);
+ }
+done:
+#endif
+ return res;
+}
+
+/*
* try_mount_one()
* Try to mount one file system.
*
@@ -1326,6 +1361,17 @@ mount_retry:
}
}
+ /* Kernel allows to use MS_RDONLY for bind mounts, but the read-only request
+ * could be silently ignored. Check it to avoid 'ro' in ntab and 'rw' in
+ * /proc/mounts.
+ */
+ if (!fake && mnt5_res == 0 &&
+ (flags & MS_BIND) && (flags & MS_RDONLY) && !is_readonly(node)) {
+
+ printf(_("mount: warning: %s seems to be mounted read-write.\n"), node);
+ flags &= ~MS_RDONLY;
+ }
+
if (fake || mnt5_res == 0) {
/* Mount succeeded, report this (if verbose) and write mtab entry. */