|############################ 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 ***
Sent an email upstream regarding this issue.
Created attachment 44199 [details, diff] cscope-tempfile.patch /* * Cscope patch by REXOTEC - version 15-5 and minors * <research@rexotec.com> */
Oops, I didn't even see the patch in the advisory... vim/emacs herd.. please verify/apply patch.
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.
Thanks Matthew. This one is ready for GLSA
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>
hi, i will take care of this... best regards florian [ruth]
Created attachment 44571 [details, diff] 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
Patch looks ok to me. Seemes to work fine.
+char tmpdir[2048]; /* temporary directory */ ... + tmpdir[sizeof(tmpdir)] = '\0'; I think the last line should be: tmpdir[sizeof(tmpdir) - 1] = '\0';
Created attachment 44698 [details, diff] CAN-2004-0996.patch Debian patch.
ciaranm, please apply the CAN-2004-0996.patch to cscope.
cscope-15.5-r2 patched, KEYWORDS="~x86 ~ppc sparc mips ~alpha ~arm ~hppa ~amd64 ~ia64 ~s390 ~ppc64"
arches, please mark cscop-15.5-r2 stable.
Stable on IA64.
stable on ppc64
Stable on amd64
stable on ppc
Stable on alpha.
Stable on hppa.
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)
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.
Yes, if I go back to cscope-15.5-r1 the above "build a cscope database" command works just fine.
Meh! Yeah, looks like this breaks some of the interfaces to cscope.
Going back to ebuild status the time we find a cleaner patch.
We could go back to Florian's first patch (+ modifications from comment #10). What do you guys think?
Created attachment 45208 [details, diff] Corrected Florian's patch Here is Florian's patch, corrected with comment #10
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 ?
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)
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.
Sent an email upstream with both patches. Waiting for a response with his opinion.
Created attachment 45342 [details, diff] Debian patch from their cscope_15.5-1.1
Debian patch is identical to the Ubuntu patch, which seems to have been changed in the mean time (compared to attachment 44698 [details, diff]).
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...
Created attachment 45463 [details, diff] cscope-tempfile.diff Fixed typo in Koon's updated patch. - if (ret == NULL)s + if (ret == NULL)
mkennedy, please apply latest patch.
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.
-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.
ppc keyworded
Stable on sparc.
arm/hppa/ia64/s390 stable
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.
Calling amd64 to test and mark 15.5-r3 stable, apparently they were forgotten...
done by dragonheart on ppc
amd64 done
GLSA 200412-11 mips, please mark stable to benefit from GLSA.
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
Stable on mips