On Wed, Nov 18, 2009 at 04:09:18PM +0000, Terry Burton wrote: > I've not yet had the chance to give any attention to solving the issue > in the way that you suggest, however I imagine that there may be > complications for filesystems that have naming restrictions? OK, I have a little time. See the patch below. Karel >From b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8 Mon Sep 17 00:00:00 2001 From: Karel Zak <kzak@xxxxxxxxxx> Date: Thu, 19 Nov 2009 15:56:12 +0100 Subject: [PATCH] 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@xxxxxxxxxxxxxxxxx> Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> --- configure.ac | 1 + mount/mount.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index fc0b9e1..d0356fd 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 23d70cb..3eafa92 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. */ -- 1.6.5.1 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html