https://bugzilla.novell.com/show_bug.cgi?id=754443 https://bugzillafiles.novell.org/attachment.cgi?id=487179 diff -Naurp samba-3.5.3/source3/configure.in samba-3.5.3.oden/source3/configure.in --- samba-3.5.3/source3/configure.in 2012-05-04 11:40:21.000000000 +0000 +++ samba-3.5.3.oden/source3/configure.in 2012-05-04 11:41:04.000000000 +0000 @@ -674,6 +674,11 @@ AC_CHECK_HEADERS(rpcsvc/yp_prot.h,,,[[ #endif ]]) +# do we have sys/fsuid.h and setfsuid()? +AC_CHECK_HEADERS([sys/fsuid.h]) +AC_CHECK_FUNC(setfsuid, , [AC_MSG_ERROR([System does not support + setfsuid()])]) + ## These fail to compile on IRIX so just check for their presence AC_CHECK_HEADERS(sys/mode.h,,,) diff -Naurp samba-3.5.3/client/mount.cifs.c samba-3.5.3.oden/client/mount.cifs.c --- samba-3.5.3/client/mount.cifs.c 2012-05-04 11:40:21.000000000 +0000 +++ samba-3.5.3.oden/client/mount.cifs.c 2012-05-04 11:43:52.000000000 +0000 @@ -31,6 +31,9 @@ #include <sys/stat.h> #include <sys/utsname.h> #include <sys/socket.h> +#ifdef HAVE_SYS_FSUID_H +#include <sys/fsuid.h> +#endif /* HAVE_SYS_FSUID_H */ #include <arpa/inet.h> #include <getopt.h> #include <errno.h> @@ -1229,6 +1232,58 @@ static int check_mtab(const char *progna } +/* + * chdir() into the mountpoint and determine "realpath". We assume here that + * "mountpoint" is a statically allocated string and does not need to be freed. + */ +static int +acquire_mountpoint(char **mountpointp) +{ + int rc; + uid_t realuid, oldfsuid; + gid_t oldfsgid; + char *mountpoint; + + /* + * We change the fsuid to the real uid to ensure that + * the mounting user actually has access to the mountpoint. + * + * The mount(8) manpage does not state that users must be able to + * chdir into the mountpoint in order to mount onto it, but if we + * allow that, then an unprivileged user could use this program to + * "probe" into directories to which he does not have access. + */ + realuid = getuid(); + if (realuid != 0) { + oldfsuid = setfsuid(realuid); + oldfsgid = setfsgid(getgid()); + } + + rc = chdir(*mountpointp); + if (rc) { + fprintf(stderr, "Couldn't chdir to %s: %s\n", *mountpointp, + strerror(errno)); + rc = EX_USAGE; + goto restore_privs; + } + + mountpoint = realpath(".", NULL); + if (!mountpoint) { + fprintf(stderr, "Unable to resolve %s to canonical path: %s\n", + *mountpointp, strerror(errno)); + rc = EX_SYSERR; + } + + *mountpointp = mountpoint; +restore_privs: + if (realuid != 0) { + setfsuid(oldfsuid); + setfsgid(oldfsgid); + } + + return rc; +} + int main(int argc, char ** argv) { int c; @@ -1448,14 +1503,9 @@ int main(int argc, char ** argv) mount_cifs_usage(stderr); } - /* 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; + rc = acquire_mountpoint(&mountpoint); + if (rc) goto mount_exit; - } rc = check_mountpoint(thisprogram, mountpoint); if (rc) diff -Naurp samba-3.5.3/docs/manpages/mount.cifs.8 samba-3.5.3.oden/docs/manpages/mount.cifs.8 --- samba-3.5.3/docs/manpages/mount.cifs.8 2010-05-17 08:53:17.000000000 +0000 +++ samba-3.5.3.oden/docs/manpages/mount.cifs.8 2012-05-04 11:43:27.000000000 +0000 @@ -601,7 +601,8 @@ The variable may contain the pathname of a file to read the password from\&. A single line of input is read and used as the password\&. .SH "NOTES" .PP -This command may be used only by root, unless installed setuid, in which case the noeexec and nosuid mount flags are enabled\&. When installed as a setuid program, the program follows the conventions set forth by the mount program for user mounts\&. +This command may be used only by root, unless installed setuid, in which case the noeexec and nosuid mount flags are enabled\&. When installed as a setuid program, the program follows the conventions set forth by the mount program for user mounts, with the added restriction that users must be able to chdir() into the +mountpoint prior to the mount in order to be able to mount onto it. .PP Some samba client tools like smbclient(8) honour client\-side configuration parameters present in smb\&.conf\&. Unlike those client tools, \fImount\&.cifs\fR