mount.cifs: check for invalid characters in device name and mountpoint
authorJeff Layton <jlayton@redhat.com>
Tue, 26 Jan 2010 13:36:03 +0000 (08:36 -0500)
committerKarolin Seeger <kseeger@samba.org>
Mon, 29 Mar 2010 07:41:00 +0000 (09:41 +0200)
It's apparently possible to corrupt the mtab if you pass embedded
newlines to addmntent. Apparently tabs are also a problem with certain
earlier glibc versions. Backslashes are also a minor issue apparently,
but we can't reasonably filter those.

Make sure that neither the devname or mountpoint contain any problematic
characters before allowing the mount to proceed.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
(cherry picked from commit ae24005a5a2c165dfd9b859bf1c02b5f7e967be5)

client/mount.cifs.c

index 6adec92b0c59b14502c2e52976f54c43da23a8ba..6662eea48e6e4f046919d0cfca1bb2c81ae45ba3 100644 (file)
@@ -1165,6 +1165,36 @@ static void print_cifs_mount_version(void)
                MOUNT_CIFS_VENDOR_SUFFIX);
 }
 
+/*
+ * This function borrowed from fuse-utils...
+ *
+ * glibc's addmntent (at least as of 2.10 or so) doesn't properly encode
+ * newlines embedded within the text fields. To make sure no one corrupts
+ * the mtab, fail the mount if there are embedded newlines.
+ */
+static int check_newline(const char *progname, const char *name)
+{
+    char *s;
+    for (s = "\n"; *s; s++) {
+        if (strchr(name, *s)) {
+            fprintf(stderr, "%s: illegal character 0x%02x in mount entry\n",
+                    progname, *s);
+            return EX_USAGE;
+        }
+    }
+    return 0;
+}
+
+static int check_mtab(const char *progname, const char *devname,
+                       const char *dir)
+{
+       if (check_newline(progname, devname) == -1 ||
+           check_newline(progname, dir) == -1)
+               return EX_USAGE;
+       return 0;
+}
+
+
 int main(int argc, char ** argv)
 {
        int c;
@@ -1608,6 +1638,10 @@ mount_retry:
        if (verboseflag)
                fprintf(stderr, "\n");
 
+       rc = check_mtab(thisprogram, dev_name, mountpoint);
+       if (rc)
+               goto mount_exit;
+
        if (!fakemnt && mount(dev_name, ".", "cifs", flags, options)) {
                switch (errno) {
                case ECONNREFUSED: