Bugzilla – Bug 62677
VUL-0: CVE-2004-0994: xzgv: integer overflows that lead to buffer overflows
Last modified: 2021-10-27 15:18:02 UTC
Hi, here is a post for zgv from Bugtraq ML.
<!-- SBZ_reproduce --> Von: infamous41md@hotpop.com An: bugtraq <bugtraq@securityfocus.com> Betreff: zgv image viewing heap overflows Datum: Mon, 25 Oct 2004 21:07:17 -0400 ++++++++++++++++++++++++++++++++++++++++++++ Subject: zgv multiple heap overflows ++++++++++++++++++++++++++++++++++++++++++++ Product: zgv is a picture viewer with a thumbnail-based file selector, for the Linux and FreeBSD console (it uses svgalib). It's pretty featureful, and is probably the best svgalib-based viewer. (It can also be built to use SDL if you prefer.) Lots of people have told me they like it, where "lots" = "oh, it must be at least two or three", and you can't ask for a more ringing endorsement than that. Well, you could, but I'm not sure you'd get it. :-) zgv supports most popular formats, and allows panning and fit-to-screen methods of viewing, slideshows, scaling, gamma adjustment, etc. http://www.svgalib.org/rus/zgv/ ++++++++++++++++++++++++++++++++++++++++++++ Vulnerable: I tested latest, zgv-5.5.orig. ++++++++++++++++++++++++++++++++++++++++++++ Summary: zgv uses malloc() frequently to allocate memory for storing image data. When calculating how much to allocate, user supplied data from image headers is multiplied and/or added without any checks for arithmetic overflows. We can overflow numerous calculations, and cause small buffers to be allocated. Then we can overflow the buffer, and eventually execute code. There are a total of 11 overflows that are exploitable to execute arbitrary code. ++++++++++++++++++++++++++++++++++++++++++++ Details: 01]readbmp.c:180: if ((work_bmap = *bmap = calloc (w * (h + 2) * bytepp,1)) == NULL) 02]readgif.c:498: if((im->image=(byte *)malloc(width*height))==NULL) 03]readgif.c:606:if((*theimageptr= (byte *)malloc(ginfo->width*ginfo->height))==NULL) 04]readmrf.c:107: (image=calloc(w64*h64*64*64,1))==NULL) 05]readpcx.c:130:if((*bmap=malloc(w*(h+2)*bytepp))==NULL) 06]readpng.c:225:theimage=(byte *)malloc(pixelsize*width*(height+2)); 07]readpnm.c:147:if((*bmap=malloc(w*(h+2)*bytepp))==NULL) 08]readprf.c:205:if((*bmap=work_bmap=malloc(width*(height+2)*planes))==NULL) 09]readtiff.c:89:if((image=*bmap=work_bmap= malloc(numpix*sizeof(uint32)+width*3*2))==NULL) 10]readxpm.c:183:if((colchars=malloc(ncols*sizeof(struct colchars_tag)))==NULL) 11]readxpm.c:372:if((*bmap=malloc(w*(h+2)*bytepp))==NULL) ++++++++++++++++++++++++++++++++++++++++++++ Exploits: There is a C file for each hole above. The exploit for the first xpm hole, #10, demonstrates code execution, the rest just crash zgv. The only one I couldn't get working is the second gif hole, #3 from above. That is in the file ximage_other_gif.c. However, all are suitable for code execution with some work. I just didn't have the time. ++++++++++++++++++++++++++++++++++++++++++++ Note: There was also a hole in: 01]readpcd.c:42:if((*bmap=malloc(w*(h+3-*output_type)*(*output_type)))==NULL) I couldn't find the PCD file format anywhere for free on the web, and didn't pursue this further. I didn't see anything that would make it not exploitable though, so it looks valid to me. ++++++++++++++++++++++++++++++++++++++++++++ Vendor: Was not contacted. ++++++++++++++++++++++++++++++++++++++++++++ -- -sean
Created attachment 25476 [details] ximage_zgv.tar.gz do not trust this exploit!
Looks like we do not ship this nice little tool anymore.
dead!
<!-- SBZ_reopen -->Reopened by thomas@suse.de at Fri Oct 29 08:37:45 2004
These bugs seem to affect xzgv too.
Ouch, I'll take a look...
(should have clicked "Accept bug" also...)
Created attachment 25619 [details] multiplication overflow check prototype Okay, same problems exists in xzgv, indeed. Hmm, would a check like this work? Checking every write access to the buffer would be a PITA (especially for the implementation of the other image formats...), but I'd like to have someone more familiar with ANSI C types and bit operators to check whether this actually works on all of our platforms and equally important, will continue to work with later GCC versions...
What does (size_t ~0) do? :) Assuming that all variables used are unsigned you can try the following check: #include <limits.h> ... if(width > UINT_MAX / height) EXIT if( (width * height) > UINT_MAX / 3) EXIT malloc()
And yes. width and height should be > 0 :)
(size_t) ~0 does a bitwise inversion of a '0' of type size_t -- at least I hope so... Thinking about it, it should rather be ~((size_t) 0). Since size_t is unsigned by definition, you'll get the largest number available for size_t, as size_t isn't necessarily "unsigned int" (size_t is defined as the largest unsigned integer type available on the platform, if I'm not mistaken) and I haven't found any SIZE_T_MAX #define... Is there anything wrong with this?
Created attachment 25749 [details] Proposed fix for multiplication overflow Okay, I think this patch should fix it. Can someone take a close look please whether I've missed something? Would be embarrassing if we would issue an update that does not fix the vulnerability...
looks good. thank you! :)
Okay, submitted packages for 8.[12]-i386, 9.[012]-{i386,x86_64} and STABLE as well as a patchinfo.
<!-- SBZ_reopen -->Reopened by thomas@suse.de at Mon Nov 15 09:56:39 2004
reopened for tracking by sec-team
released updated packages on thursday...
CAN-2004-0994
CVE-2004-0994: CVSS v2 Base Score: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)