]> err.no Git - util-linux/commitdiff
mount: check for unsuccessful read-only bind mounts
authorKarel Zak <kzak@redhat.com>
Thu, 19 Nov 2009 14:56:12 +0000 (15:56 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 19 Nov 2009 14:56:12 +0000 (15:56 +0100)
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>
configure.ac
mount/mount.c

index fc0b9e1b8a183618908da95edbb9543bea23f951..d0356fdb3019e8ec37254649559e8d591938e486 100644 (file)
@@ -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 \
index 23d70cb14ce7a46d0c160150a973a38bd8c1099d..3eafa92ac64244fe2d3822225ce034a2ffd9264d 100644 (file)
@@ -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.  */