]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
mount.cifs: take extra care that mountpoint isn't changed during mount
authorJeff Layton <jlayton@redhat.com>
Tue, 26 Jan 2010 13:45:58 +0000 (08:45 -0500)
committerKarolin Seeger <kseeger@samba.org>
Thu, 6 May 2010 12:13:50 +0000 (14:13 +0200)
It's possible to trick mount.cifs into mounting onto the wrong directory
by replacing the mountpoint with a symlink to a directory. mount.cifs
attempts to check the validity of the mountpoint, but there's still a
possible race between those checks and the mount(2) syscall.

To guard against this, chdir to the mountpoint very early, and only deal
with it as "." from then on out.

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

source3/client/mount.cifs.c

index 92dd68f77db0d4020b16b2714ad61d3d6d02fac2..4d8162c501ae93c9ba609815258f364f74d859ab 100644 (file)
@@ -190,7 +190,7 @@ check_mountpoint(const char *progname, char *mountpoint)
        struct stat statbuf;
 
        /* does mountpoint exist and is it a directory? */
-       err = stat(mountpoint, &statbuf);
+       err = stat(".", &statbuf);
        if (err) {
                fprintf(stderr, "%s: failed to stat %s: %s\n", progname,
                                mountpoint, strerror(errno));
@@ -1420,6 +1420,14 @@ int main(int argc, char ** argv)
        }
 
        /* make sure mountpoint is legit */
+       rc = chdir(mountpoint);
+       if (rc) {
+               fprintf(stderr, "Couldn't chdir to %s: %s\n", mountpoint,
+                               strerror(errno));
+               rc = EX_USAGE;
+               goto mount_exit;
+       }
+
        rc = check_mountpoint(thisprogram, mountpoint);
        if (rc)
                goto mount_exit;
@@ -1482,13 +1490,23 @@ int main(int argc, char ** argv)
        
        /* BB save off path and pop after mount returns? */
        resolved_path = (char *)malloc(PATH_MAX+1);
-       if(resolved_path) {
-               /* Note that if we can not canonicalize the name, we get
-               another chance to see if it is valid when we chdir to it */
-               if (realpath(mountpoint, resolved_path)) {
-                       mountpoint = resolved_path; 
-               }
+       if (!resolved_path) {
+               fprintf(stderr, "Unable to allocate memory.\n");
+               rc = EX_SYSERR;
+               goto mount_exit;
        }
+
+       /* Note that if we can not canonicalize the name, we get
+          another chance to see if it is valid when we chdir to it */
+       if(!realpath(".", resolved_path)) {
+               fprintf(stderr, "Unable to resolve %s to canonical path: %s\n",
+                               mountpoint, strerror(errno));
+               rc = EX_SYSERR;
+               goto mount_exit;
+       }
+
+       mountpoint = resolved_path;
+
        if(got_user == 0) {
                /* Note that the password will not be retrieved from the
                   USER env variable (ie user%password form) as there is
@@ -1622,7 +1640,7 @@ mount_retry:
        if (verboseflag)
                fprintf(stderr, "\n");
 
-       if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) {
+       if (!fakemnt && mount(dev_name, ".", "cifs", flags, options)) {
                switch (errno) {
                case ECONNREFUSED:
                case EHOSTUNREACH: