Bug 71595 - dev-util/cscope: Race condition on temporary file
Bug#: 71595 Product:  Gentoo Security Version: unspecified Platform: All
OS/Version: All Status: RESOLVED Severity: minor Priority: P2
Resolution: FIXED Assigned To: security@gentoo.org Reported By: lewk@gentoo.org
Component: Vulnerabilities
URL:  http://www.securityfocus.com/archive/1/381443
Summary: dev-util/cscope: Race condition on temporary file
Keywords:  
Status Whiteboard: B3 [glsa] lewk
Opened: 2004-11-17 13:53 0000
Description:   Opened: 2004-11-17 13:53 0000
|############################ REXOTEC(dot)COM ###############################
|
|=-----=[ ADV RX171104 - Cscope :: Race condition on temporary file  ]-----=|
|
|
|=---[ - INFORMATION
     `----------------------------------------------------------------------|
   VulnDiscovery:       2003/05/21
   Release Date :       2004/11/17
   Author       :       Gangstuck / Psirac <research@rexotec.com>

   Application  :       Cscope
   Affected     :       All version (last one is cscope-15.5)
   Platforms    :       Linux, SCO, SunOS/Solaris, ...
   Risk         :       Critical
   Severity     :       Allow local user to compromise filesystem.

   Vendor       :       http://cscope.sourceforge.net/
   Reference    :       http://www.rexotec.com/advisory/RX171104.html

   Status       :       vendor has just been notified.


|=---[ - SUMMARY OVERVIEW
     `----------------------------------------------------------------------|

   Cscope is a developper's tool under the BSD license used to browse 
   source code.

   His Unix pedigree is impeccable and has originally been developped at 
   Bell Labs back in PDP-11's days. Cscope was a part of the official 
   AT&T Unix distribution for many years and has been used to manage
   projects involving 20 million lines of code !


|=---[ - VULNERABILITY OVERVIEW
     `----------------------------------------------------------------------|

   First, the temporary directory (P_tmpdir="/tmp") is badly handled 
   in every myfopen() internal call.
   As all we know, creation of predictable temporary file allows any 
   local attacker to remove arbitrary files on the vulnerable file 
   system via the infamous symlink vulnerability.

        /src/main.c :
           ----------;

                [...]
                char    temp1 [PATHLEN + 1];     /* temporary file name */
                char    temp2 [PATHLEN + 1];     /* temporary file name */
                [...]
                tmpdir = mygetenv("TMPDIR", TMPDIR);
                [...]
                /* create the temporary file names */
                pid = getpid();
                (void) sprintf(temp1, "%s/cscope%d.1", tmpdir, pid);
                (void) sprintf(temp2, "%s/cscope%d.2", tmpdir, pid);
                [...]
                
      Before us are the computing of two predictable files names (resulting
      in a schema like "/tmp/cscopeNEXTPID.numba"). So, we just have to probe 
      the pid numba and make the same template which to be used for
      temporary file creation. Then,  cscope handle the files with
      wrong set of flags and compromise root filesystem due 
      to symlink vulnerability.
        

|=---[ - EXPLOITS - Proof of concept
     `----------------------------------------------------------------------|

*** CUT -- See URL ***

------- Comment #1 From Luke Macken (RETIRED) 2004-11-17 14:11:56 0000 -------
Sent an email upstream regarding this issue.

------- Comment #2 From Luke Macken (RETIRED) 2004-11-17 19:34:13 0000 -------
Created an attachment (id=44199) [details]
cscope-tempfile.patch

/*
 * Cscope patch by REXOTEC - version 15-5 and minors
 *		<research@rexotec.com>
 */

------- Comment #3 From Luke Macken (RETIRED) 2004-11-17 19:35:45 0000 -------
Oops, I didn't even see the patch in the advisory...

vim/emacs herd.. please verify/apply patch.

------- Comment #4 From Matthew Kennedy (RETIRED) 2004-11-18 00:59:32 0000 -------
I have applied the patch which will work on any arch using glibc.  Users should
upgrade from dev-util/cscope-15.5 to 15.5-r1.

------- Comment #5 From Sune Kloppenborg Jeppesen 2004-11-18 01:43:15 0000 -------
Thanks Matthew.

This one is ready for GLSA

------- Comment #6 From Luke Macken (RETIRED) 2004-11-18 05:09:20 0000 -------
Just recieved message from upstream saying that the patch is insufficient.

Moving bug to inhouse status; we should probably remove the patch and develop something internally because the upstream seems pretty stumped.  We've had plent of tempfile vulnerabilities latley, I'm sure we can figure this one out... unless someone has a better plan of action?

<upstream email>
Well, I can't verify it was 'Rexolab' who reported this, but yes, I
did receive a report about this at the SF.net bug tracker for cscope:

https://sourceforge.net/tracker/index.php?func=detail&aid=1062807&group_id=4664&atid=104664

Whoever posted that thing never bothered to suggest a solution, though,
and the solution suggested by Rexolab in his post to Bugtraq is
insufficient, which makes me suspect he didn't follow our discussion on
that bug report, either.

I've been pondering this issue, but haven't arrived at a good solution
yet.  Lack of time and lack of expertise in such matters both apply...

-- 
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
</upstream email>

------- Comment #7 From Florian Schilhabel (RETIRED) 2004-11-18 05:28:44 0000 -------
hi,
i will take care of this...

best regards

florian [ruth]

------- Comment #8 From Florian Schilhabel (RETIRED) 2004-11-23 07:40:12 0000 -------
Created an attachment (id=44571) [details]
the first patch

please note, that the patch is some sort of a first try on this issue...

the authors says, the program is running on all kind of arches; i just dont
have all the machines to test for availability on mkdtemp()

so please check and tell me, if something like that would be ok...
best regards
florian

------- Comment #9 From Dan Margolis (RETIRED) 2004-11-23 08:23:30 0000 -------
Patch looks ok to me. Seemes to work fine. 

------- Comment #10 From Matthew Kennedy (RETIRED) 2004-11-23 11:41:25 0000 -------
+char	tmpdir[2048];		/* temporary directory */
...
+	tmpdir[sizeof(tmpdir)] = '\0';

I think the last line should be:

tmpdir[sizeof(tmpdir) - 1] = '\0';

------- Comment #11 From Sune Kloppenborg Jeppesen 2004-11-25 01:49:53 0000 -------
Created an attachment (id=44698) [details]
CAN-2004-0996.patch

Debian patch.

------- Comment #12 From Luke Macken (RETIRED) 2004-11-28 10:39:52 0000 -------
ciaranm, please apply the CAN-2004-0996.patch to cscope.

------- Comment #13 From Ciaran McCreesh 2004-11-28 11:31:39 0000 -------
cscope-15.5-r2 patched, KEYWORDS="~x86 ~ppc sparc mips ~alpha ~arm ~hppa ~amd64
~ia64 ~s390 ~ppc64"

------- Comment #14 From Luke Macken (RETIRED) 2004-11-28 11:52:27 0000 -------
arches, please mark cscop-15.5-r2 stable.

------- Comment #15 From Tim Yamin (RETIRED) 2004-11-28 13:16:24 0000 -------
Stable on IA64.

------- Comment #16 From Markus Rothe 2004-11-28 13:26:17 0000 -------
stable on ppc64

------- Comment #17 From Karol Wojtaszek (RETIRED) 2004-11-28 13:52:39 0000 -------
Stable on amd64

------- Comment #18 From Luca Barbato 2004-11-28 23:00:20 0000 -------
stable on ppc

------- Comment #19 From Bryan Østergaard (RETIRED) 2004-11-29 18:24:13 0000 -------
Stable on alpha.

------- Comment #20 From Guy Martin 2004-11-30 04:30:03 0000 -------
Stable on hppa.

------- Comment #21 From Matthew Kennedy (RETIRED) 2004-11-30 12:11:34 0000 -------
Anyone testing this?  This release (15.5-r2) doesn't seem to work.

cscope-15.5-r1:

mkennedy@camus:~/work/gyach$ cscope -vRl
Building cross-reference...
>> 1main
cscope: 6 lines
src/main.c main 2210 int main( int argc, char **argv ) {
src/md5.c main 50 main()
src/md5.c main 87 main()
{arch}/++pristine-trees/unlocked/vendor/vendor--gyach/vendor--gyach--0.9.8/mkennedy@gentoo.org--2005-misc/vendor--gyach--0.9.8--patch-2/src/main.c main 2210 int main( int argc, char **argv ) {
{arch}/++pristine-trees/unlocked/vendor/vendor--gyach/vendor--gyach--0.9.8/mkennedy@gentoo.org--2005-misc/vendor--gyach--0.9.8--patch-2/src/md5.c main 50 main(){arch}/++pristine-trees/unlocked/vendor/vendor--gyach/vendor--gyach--0.9.8/mkennedy@gentoo.org--2005-misc/vendor--gyach--0.9.8--patch-2/src/md5.c main 87 main()>> q
mkennedy@camus:~/work/gyach$ 

And here is cscope-15.5-r2 (the security fix).  The result is reproducable on 2 pretty different x86 machines:

mkennedy@camus:~/work/gyach$ cscope -vRl
Building cross-reference...
>> 1main
Cannot open file /tmp/cscopidcEVg
cscope: 0 lines
Segmentation fault
mkennedy@camus:~/work/gyach$

Here's a backtrace I haven't had time time investigate further.

mkennedy@camus:~/work/gyach$ gdb -q /usr/bin/cscope
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) set args "-vRl"
(gdb) r
Starting program: /usr/bin/cscope "-vRl"
Building cross-reference...
>> 1main
Cannot open file /tmp/cscop85vG6n
cscope: 0 lines

Program received signal SIGSEGV, Segmentation fault.
0xb7ed38af in getc () from /lib/libc.so.6
(gdb) bt full
#0  0xb7ed38af in getc () from /lib/libc.so.6
No symbol table info available.
#1  0x0805c374 in main (argc=0, argv=0xbffff348) at main.c:608
        buf = "1main\000\000\uffff", '\0' <repeats 12 times>, "\uffff\210\uffff\uffff\uffff\uffff\uffff\uffff\036,\000\000\000\000\000\001\000\000\000\000\000\220\uffff\uffff", '\0' <repeats 28 times>, "\001", '\0' <repeats 39 times>, "\006\000\000\000\uffff\210\uffff\uffff\uffff\uffff\017\000Q", '\0' <repeats 27 times>, ".\uffff\uffff\uffff\000\000\000\000L\016\000\uffff4\200\004\b\b\000\000\000\uffff\uffff\uffff\uffff\236\236\uffff\uffff4\200\004\b\000\001\000\000\uffff\uffff\uffff\uffff\000\000\000-\003\000\000\000n\uffff\uffff\uffff\000\uffff\uffff\uffff\b\000\000\0004\200\004\b@\235\004\bLinux", '\0' <repeats 26 times>
        names = (FILE *) 0xb7f9c9b8
        oldnum = 0
        path = '\0' <repeats 15 times>, "#\016p\uffff\uffff1\216\004\b\uffff\231\uffff\uffffL\016\000\uffff\000\000\000\000\000\000\000\000\024\uffff\uffff\uffff\uffff0\uffff\uffff\uffff\235\uffff\uffff\t\221\004\b\000\000\000\000\000\000\000\000 ", '\0' <repeats 11 times>, "\200\236\uffff\uffff<M\uffff\uffff\uffff\uffff\uffff\uffff\020\232\uffff\uffff\004\000\000\000\uffff\234\uffff\uffff\020\235\uffff\uffffL\016\000\uffff\uffff\221\uffff\uffffZ\220\004\b\uffff\uffff\uffff\uffff5&\uffff\uffffZ\220\004\b\216\uffffw\001\234\211\004\b|\uffff\uffff\uffffX\221\uffff\uffff\002\000\000\000\020\235\uffff\uffff\001\000\000\000\000\000\000\000\001\000\000\000X\221\uffff\uffff\000\000\000\000\000\000\000\000|\uffff\uffff\uffff", '\0' <repeats 20 times>, "\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff\uffff"...
        oldrefs = (FILE *) 0x0
        s = 0xbffff015 ""
        c = 0
        i = 0
        pid = 0
        stat_buf = {st_dev = 8450, __pad1 = 0, st_ino = 15, st_mode = 17407,
  st_nlink = 10, st_uid = 0, st_gid = 0, st_rdev = 0, __pad2 = 0,
  st_size = 888, st_blksize = 131072, st_blocks = 1, st_atim = {
    tv_sec = 1101837263, tv_nsec = 210196346}, st_mtim = {tv_sec = 1101838934,
    tv_nsec = 49140416}, st_ctim = {tv_sec = 1101838934, tv_nsec = 49140416},
  __unused4 = 0, __unused5 = 0}
(gdb)

------- Comment #22 From Greg Kroah-Hartman 2004-12-01 09:58:45 0000 -------
Ick, I think this patch just caused a bug.

If you do:
$ cscope -q -b -i cscope.files -k

I get the following error:
  Removed file /home/greg/tmp/cscopaTa89u because write failed: File exists

and the building of the cscope database for the files I specified does not happen.

------- Comment #23 From Greg Kroah-Hartman 2004-12-01 10:02:48 0000 -------
Yes, if I go back to cscope-15.5-r1 the above "build a cscope database" command
works just fine.

------- Comment #24 From Ciaran McCreesh 2004-12-01 10:44:08 0000 -------
Meh! Yeah, looks like this breaks some of the interfaces to cscope.

------- Comment #25 From Thierry Carrez (RETIRED) 2004-12-01 10:51:22 0000 -------
Going back to ebuild status the time we find a cleaner patch.

------- Comment #26 From Luke Macken (RETIRED) 2004-12-02 09:40:00 0000 -------
We could go back to Florian's first patch (+ modifications from comment #10). 
What do you guys think?

------- Comment #27 From Thierry Carrez (RETIRED) 2004-12-03 08:28:08 0000 -------
Created an attachment (id=45208) [details]
Corrected Florian's patch

Here is Florian's patch, corrected with comment #10

------- Comment #28 From Thierry Carrez (RETIRED) 2004-12-03 08:29:48 0000 -------
I don't feel very comfortable applying modified Florian's patch without him
being here to double-check it's clean... but I guess we don't have much choice
?

------- Comment #29 From Luke Macken (RETIRED) 2004-12-03 09:05:42 0000 -------
I don't think we should blindly apply this patch without making sure it is
sufficient.  Before we come to any conclusions, I think it would be best for
florian to get involved in the bug
(https://sourceforge.net/tracker/index.php?func=detail&aid=1062807&group_id=4664&atid=104664)
 to bring him up to speed a little bit and to see what the dev has to say.

(Also, this is CAN-2004-0996)

------- Comment #30 From Matthias Geerdsen 2004-12-05 11:56:58 0000 -------
Debian has published a fixed version (15.5-1.1).
Changelog:
* NMU to fix temp file security hole. Closes: #282815 (CAN-2004-0996)
   * Incorporates a patch by Martin Pitt <martin.pitt@canonical.com>:
   * SECURITY UPDATE: insecure temp file creation vulnerability
   * src/main.c:
     - modified the temporary file creation procedure
   * References:
     - CAN-2004-0996
     - http://lists.netsys.com/pipermail/full-disclosure/2004-November/029341.html
   * Thanks to Gerardo Di Giacomo <gerardo@linux.it> for his assistance with
     the patch

Haven't seen it on the mirrors yet though, but should be available soon.

------- Comment #31 From Luke Macken (RETIRED) 2004-12-05 13:39:43 0000 -------
Sent an email upstream with both patches.  Waiting for a response with his
opinion.

------- Comment #32 From Matthias Geerdsen 2004-12-05 13:58:17 0000 -------
Created an attachment (id=45342) [details]
Debian patch from their cscope_15.5-1.1

------- Comment #33 From Matthias Geerdsen 2004-12-05 14:03:03 0000 -------
Debian patch is identical to the Ubuntu patch, which seems to have been changed
in the mean time (compared to attachment 44698 [details]).

------- Comment #34 From Luke Macken (RETIRED) 2004-12-06 20:26:03 0000 -------
Response from upstream:

- - -
The patch under link [2] (Debian/Ubuntu) is effectively a placebo, caused by serious lack of analysis.  It grasps much too short, because the author didn't
understand the way cscope (re)uses temp files.  I've explained this several times, both in our bug tracker and in my reply mail to Rexolab's post.  I fail to see how people managed to miss that.

Patch [1] (Ours, woo!) (i.e. a private temp file directory) is essentially the same thing we'll eventually do (work done by Neil Horman at redhat).  Of the suggestions I've seen, I'm quite sure that's the only one that can work without re-implementing the entire way cscope handles temp files.
- - -

Ciaran, please apply patch from comment #27...

------- Comment #35 From Luke Macken (RETIRED) 2004-12-07 13:15:00 0000 -------
Created an attachment (id=45463) [details]
cscope-tempfile.diff

Fixed typo in Koon's updated patch.

- if (ret == NULL)s
+ if (ret == NULL)

------- Comment #36 From Luke Macken (RETIRED) 2004-12-09 13:01:56 0000 -------
mkennedy, please apply latest patch.

------- Comment #37 From Luke Macken (RETIRED) 2004-12-10 09:48:14 0000 -------
mkennedy is MIA at the moment, so can anyone in the Vim or Emacs herd please
apply this patch?  This issue needs to get resolved soon.

------- Comment #38 From Ryan Phillips (RETIRED) 2004-12-10 17:06:51 0000 -------
-r3 has been commited and has been unmasked for x86... I'm going to leave the
bug open, so I can go back and delete the old packages and the
cscope-15.5-can-2004-0996.patch which is no longer needed.

Other architectures please unmask -r3, and security please issue a GLSA.

------- Comment #39 From Daniel Black 2004-12-10 19:44:01 0000 -------
ppc keyworded

------- Comment #40 From Markus Rothe 2004-12-10 23:53:50 0000 -------
stable on ppc64

------- Comment #41 From Jason Wever (RETIRED) 2004-12-11 07:11:22 0000 -------
Stable on sparc.

------- Comment #42 From SpanKY 2004-12-11 15:31:35 0000 -------
arm/hppa/ia64/s390 stable

------- Comment #43 From PaX Team 2004-12-12 04:32:20 0000 -------
the rexotec patch 1. breaks cscope/vim (see bug #72160), 2. is not needed at
all with the other fix that uses mkdtemp (unprivileged users can't create
symlinks in the mode 0700 directory, which is the original source of the
problem with /tmp). on a sidenote, snprintf() 0 terminates the buffer itself.

------- Comment #44 From Bryan Østergaard (RETIRED) 2004-12-13 00:17:38 0000 -------
Stable on alpha.

------- Comment #45 From Thierry Carrez (RETIRED) 2004-12-13 01:37:16 0000 -------
Calling amd64 to test and mark 15.5-r3 stable, apparently they were
forgotten...

------- Comment #46 From Jochen Maes (RETIRED) 2004-12-16 06:02:40 0000 -------
done by dragonheart on ppc

------- Comment #47 From Simon Stelling (RETIRED) 2004-12-16 10:52:02 0000 -------
amd64 done

------- Comment #48 From Luke Macken (RETIRED) 2004-12-16 12:36:46 0000 -------
GLSA 200412-11

mips, please mark stable to benefit from GLSA.

------- Comment #49 From Olle Hällnäs 2004-12-18 02:54:17 0000 -------
This is a bad patch for GCC2 users.
You introduce char template[] = "cscope.XXXXXX"; and char *ret;
in the wrong place. These should at the top och the main () funtion to compile using older gcc's than 3.x on x86


------- Comment #50 From Hardave Riar (RETIRED) 2005-02-19 15:17:14 0000 -------
Stable on mips