From: Karel Zak Date: Thu, 19 Nov 2009 14:56:12 +0000 (+0100) Subject: mount: check for unsuccessful read-only bind mounts X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8;p=util-linux 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 Signed-off-by: Karel Zak --- diff --git a/configure.ac b/configure.ac index fc0b9e1b..d0356fdb 100644 --- a/configure.ac +++ b/configure.ac @@ -145,6 +145,7 @@ AC_CHECK_DECLS([_NL_TIME_WEEK_1STDAY],[],[],[[#include ]]) AC_CHECK_FUNCS( [inet_aton \ + futimens \ fsync \ getdomainname \ get_current_dir_name \ diff --git a/mount/mount.c b/mount/mount.c index 23d70cb1..3eafa92a 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -1225,6 +1225,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. */