From b7ce600d3d238ca3e82aa04ee6845afc45fb5eb8 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 19 Nov 2009 15:56:12 +0100 Subject: 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 --- mount/mount.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'mount/mount.c') diff --git a/mount/mount.c b/mount/mount.c index 23d70cb14..3eafa92ac 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. */ -- cgit v1.2.3-55-g7522