Bug 3743 - mount.cifs crashes when run as an ordinary user
Summary: mount.cifs crashes when run as an ordinary user
Status: RESOLVED FIXED
Alias: None
Product: CifsVFS
Classification: Unclassified
Component: user space tools (show other bugs)
Version: 2.6
Hardware: x86 Linux
: P3 normal
Target Milestone: ---
Assignee: Steve French
QA Contact:
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-05-01 13:18 UTC by Birger Wathne
Modified: 2009-04-17 13:44 UTC (History)
2 users (show)

See Also:


Attachments
mount.cifs with debug printf inserted (33.16 KB, text/plain)
2006-05-05 11:44 UTC, Steve French
no flags Details
Replace comment for getusername with something that's correct, and removal of the offending call to free. (690 bytes, patch)
2006-06-12 05:52 UTC, Kjetil Jørgensen
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Birger Wathne 2006-05-01 13:18:42 UTC
According to the man page it is possible to set the suid bit to let ordinary users run mount.cifs.

When I do this, the mount succeeds, but mount.cifs crashes with the following backtrace

-bash-3.1$ /sbin/mount.cifs //gimle.uib.no/msidistro /tmp/mnt --verbose -o password=XXXXXXXX
parsing options: password=XXXXXX

mount.cifs kernel mount options unc=//gimle.uib.no\msidistro,ip=129.177.14.46,user=XXXXX,ver=1,password=XXXXXX
*** glibc detected *** /sbin/mount.cifs: free(): invalid pointer: 0x094d159a ***======= Backtrace: =========
/lib/libc.so.6[0x6a4f18]
/lib/libc.so.6(__libc_free+0x79)[0x6a841d]
/sbin/mount.cifs[0x804b48d]
/lib/libc.so.6(__libc_start_main+0xdc)[0x6567e4]
/sbin/mount.cifs[0x8048ee1]
======= Memory map: ========
00344000-005eb000 r-xp 00000000 21:01 3483596    /lib/libnss_ldap-2.3.90.so
005eb000-00602000 rwxp 002a7000 21:01 3483596    /lib/libnss_ldap-2.3.90.so
00602000-00611000 rwxp 00602000 00:00 0
00623000-00624000 r-xp 00623000 00:00 0          [vdso]
00624000-0063d000 r-xp 00000000 21:01 3483664    /lib/ld-2.4.so
0063d000-0063e000 r-xp 00018000 21:01 3483664    /lib/ld-2.4.so
0063e000-0063f000 rwxp 00019000 21:01 3483664    /lib/ld-2.4.so
00641000-0076d000 r-xp 00000000 21:01 3483669    /lib/libc-2.4.so
0076d000-00770000 r-xp 0012b000 21:01 3483669    /lib/libc-2.4.so
00770000-00771000 rwxp 0012e000 21:01 3483669    /lib/libc-2.4.so
00771000-00774000 rwxp 00771000 00:00 0
0079d000-0079f000 r-xp 00000000 21:01 3483672    /lib/libdl-2.4.so
0079f000-007a0000 r-xp 00001000 21:01 3483672    /lib/libdl-2.4.so
007a0000-007a1000 rwxp 00002000 21:01 3483672    /lib/libdl-2.4.so
008c7000-008d0000 r-xp 00000000 21:01 3483606    /lib/libnss_files-2.4.so
008d0000-008d1000 r-xp 00008000 21:01 3483606    /lib/libnss_files-2.4.so
008d1000-008d2000 rwxp 00009000 21:01 3483606    /lib/libnss_files-2.4.so
009a9000-009b4000 r-xp 00000000 21:01 3483675    /lib/libgcc_s-4.1.0-20060304.so.1
009b4000-009b5000 rwxp 0000a000 21:01 3483675    /lib/libgcc_s-4.1.0-20060304.so.1
00bdf000-00be3000 r-xp 00000000 21:01 3482247    /lib/libnss_dns-2.4.so
00be3000-00be4000 r-xp 00003000 21:01 3482247    /lib/libnss_dns-2.4.so
00be4000-00be5000 rwxp 00004000 21:01 3482247    /lib/libnss_dns-2.4.so
00c68000-00c77000 r-xp 00000000 21:01 3482280    /lib/libresolv-2.4.so
00c77000-00c78000 r-xp 0000e000 21:01 3482280    /lib/libresolv-2.4.so
00c78000-00c79000 rwxp 0000f000 21:01 3482280    /lib/libresolv-2.4.so
00c79000-00c7b000 rwxp 00c79000 00:00 0
00c7d000-00c7f000 r-xp 00000000 21:01 3483678    /lib/libcom_err.so.2.1
00c7f000-00c80000 rwxp 00001000 21:01 3483678    /lib/libcom_err.so.2.1
08048000-0804d000 r-xp 00000000 21:01 3319597    /sbin/mount.cifs
0804d000-0804e000 rw-p 00004000 21:01 3319597    /sbin/mount.cifs
094cf000-094f0000 rw-p 094cf000 00:00 0          [heap]
b7e00000-b7e21000 rw-p b7e00000 00:00 0
b7e21000-b7f00000 ---p b7e21000 00:00 0
b7f6e000-b7f70000 rw-p b7f6e000 00:00 0
b7f7f000-b7f80000 rw-p b7f7f000 00:00 0
bfb6a000-bfb7f000 rw-p bfb6a000 00:00 0          [stack]
Aborted
Comment 1 Steve French 2006-05-05 10:12:04 UTC
What is the version of your mount.cifs file ("/sbin/mount.cifs -V")?
Comment 2 Steve French 2006-05-05 10:22:49 UTC
Does the user or password contain a comma (',') ?
Comment 3 Steve French 2006-05-05 11:44:12 UTC
Created attachment 1891 [details]
mount.cifs with debug printf inserted

I hate to debug this the boring, old fashioned way but is seems easiest since I did not spot the problem yet the other ways.  I have created a mount.cifs.c with additional print statements before the five or six frees.  Although this is a harmless error (free of an already exiting process) I would like to fix this.

You can "gcc mount.cifs.c -o mount.cifs"  and run ./mount.cifs directly out of that directory or move it into sbin (saving your existing mount.cifs first of course) so it can be executed by "mount -t cifs" without having to run "mount.cifs //server/share /mnt" directly
Comment 4 Kjetil Jørgensen 2006-06-09 13:34:14 UTC
If you add MALLOC_CHECK_=2 to the environment, it'll probably abort() as root as well.

I experienced a similiar problem with the mount.cifs shipped with ubuntu (not sure if it's breezy badger), my version of mount.cifs says 1.6, installed version of samba is 3.0.14a. A closer inspection of trunk, with mount.cifs v. 1.10 seems to have the same problem.

Ran this trough gdb and got it to crash around line 960-something of mount.cifs.c

if(mount_user) {
  if(getuid() != 0) {
    strcat(mountent.mnt_opts,",user=");
    strcat(mountent.mnt_opts,mount_user);
  }
  free(mount_user); // Here bad malloc-mojo occurs, and with MALLOC_CHECK_=2
                    // will abort().
}

Backtracking a bit, mount_user is a char * pointer returned by the function getusername (which exists in mount.cifs.c).

The comment to this function is "caller frees username if necessary", which is sort of misleading, as it should never need to be freed (if I've understood getpwnam correctly).

getusername calls getpwuid, and the returned pointer is from the struct resulting from a successful call of getpwuid. Here the fun starts, the posix-standard says that it may be stored in a static area which may be overwritten by further calls to getpwuid, which sort of leads me to believe that the programmer shouldn't worry about freeing what it returns. The man-pages for getpwnam seems to be vague enough to interpret it both for and against freeing. Somebody with better UNIX-fu than me might know the definitive answear.

This was the most authorative-looking I found on getpwuid:
http://www.opengroup.org/onlinepubs/009695399/functions/getpwuid.html

If your libc supports it, a temporary fix is to make sure MALLOC_CHECK_=0 is set in the environment when mount.cifs get run (altough I think some systems ignores this for suid-root  executables).

Cheers!
Kjetil Jørgensen <kjetijor@pvv.ntnu.no>
Comment 5 Kjetil Jørgensen 2006-06-12 05:52:17 UTC
Created attachment 1956 [details]
Replace comment for getusername with something that's correct, and removal of the offending call to free.

Uploaded a patch with two minor changes to mount.cifs.c, fixing the comment for getusername and removed the offending call to free. It fixes mount.cifs aborting on my systems at least. :)
Comment 6 Kjetil Jørgensen 2006-06-15 11:25:23 UTC
After testing some more, it seems it's more hard to reproduce than I first thought. That is, MALLOC_CHECK_ is not going to help reproduce it in all cases :(

I do however still stand by that calling free on something returned by getpwuid/getpwnam is wrong.

-- 
Kjetil Jørgensen
Comment 7 shirishpargaonkar@gmail.com 2009-04-01 10:46:02 UTC
The fix in the attachment in comment #5 is in mount.cifs.c.
I do not see anymore of such issues, free() of the user names returned by
getpwuid and getpwnam system calls.
Ran mount.cifs with MALLOC_CHECK_=2 many times without encountering any
aborts and error stack.

I think this issue is fixed and this bug can be closed.
Comment 8 Steve French 2009-04-17 13:44:17 UTC
fixed, as Shirish notes