summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-01-26 08:35:35 -0500
committerKarolin Seeger <kseeger@samba.org>2010-03-29 09:40:59 +0200
commita395811b01e1ee40198749e45eeaf56d0093a7b6 (patch)
tree39556bf29ac941378e9c1febce6bd754accd83db /client
parentfc8689cf9ec4588d57d734999d524f6725d34b1d (diff)
downloadsamba-a395811b01e1ee40198749e45eeaf56d0093a7b6.tar.gz
mount.cifs: take extra care that mountpoint isn't changed during mount
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 a60afceaa71c0c9b53b2ec1014db5d09d777803d)
Diffstat (limited to 'client')
-rw-r--r--client/mount.cifs.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/client/mount.cifs.c b/client/mount.cifs.c
index 3baaad79371..6adec92b0c5 100644
--- a/client/mount.cifs.c
+++ b/client/mount.cifs.c
@@ -179,7 +179,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));
@@ -1378,6 +1378,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;
@@ -1440,13 +1448,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
@@ -1590,7 +1608,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: