Buffer overflow in unzip with hand-crafted ZIP file
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
unzip |
Unknown
|
Unknown
|
|||
unzip (Ubuntu) |
Fix Released
|
Low
|
Unassigned |
Bug Description
Binary package hint: unzip
When using the attached handcrafted zip file with "unzip -l" (listing), I get the following output:
$ unzip -lv hello.zip
Archive: hello.zip
Length Method Size Ratio Date Time CRC-32 Name
-------- ------ ------- ----- ---- ---- ------ ----
*** buffer overflow detected ***: unzip terminated
======= Backtrace: =========
/lib/tls/
/lib/tls/
/lib/tls/
/lib/tls/
/lib/tls/
/lib/tls/
/lib/tls/
unzip[0x80560e1]
unzip[0x8058539]
unzip[0x8058697]
unzip[0x804af3d]
unzip[0x804b20f]
/lib/tls/
unzip[0x8049391]
======= Memory map: ========
08048000-08067000 r-xp 00000000 08:07 53597 /usr/bin/unzip
08067000-08068000 r--p 0001e000 08:07 53597 /usr/bin/unzip
08068000-08069000 rw-p 0001f000 08:07 53597 /usr/bin/unzip
08069000-0807b000 rw-p 08069000 00:00 0
08646000-08667000 rw-p 08646000 00:00 0 [heap]
b7e42000-b7e4f000 r-xp 00000000 08:07 6949 /lib/libgcc_s.so.1
b7e4f000-b7e50000 r--p 0000c000 08:07 6949 /lib/libgcc_s.so.1
b7e50000-b7e51000 rw-p 0000d000 08:07 6949 /lib/libgcc_s.so.1
b7e63000-b7ea2000 r--p 00000000 08:07 11726 /usr/lib/
b7ea2000-b7ea3000 rw-p b7ea2000 00:00 0
b7ea3000-b7fff000 r-xp 00000000 08:07 75569 /lib/tls/
b7fff000-b8000000 ---p 0015c000 08:07 75569 /lib/tls/
b8000000-b8002000 r--p 0015c000 08:07 75569 /lib/tls/
b8002000-b8003000 rw-p 0015e000 08:07 75569 /lib/tls/
b8003000-b8006000 rw-p b8003000 00:00 0
b8011000-b8018000 r--s 00000000 08:07 7511 /usr/lib/
b8018000-b801a000 rw-p b8018000 00:00 0
b801a000-b801b000 r-xp b801a000 00:00 0 [vdso]
b801b000-b8037000 r-xp 00000000 08:07 76344 /lib/ld-2.9.so
b8037000-b8038000 r--p 0001b000 08:07 76344 /lib/ld-2.9.so
b8038000-b8039000 rw-p 0001c000 08:07 76344 /lib/ld-2.9.so
bfa24000-bfa39000 rw-p bffeb000 00:00 0 [stack]
Aborted
The file has been modified so to report an unknown compression method with ordinal number 0x3FFF. unzip tries to display the method number in decimal (%3u), but only reserve buffer space for 3 characters, as can be seen here (unzip-5.52, file list.c, function list_files, around line 114):
char methbuf[8];
static ZCONST char dtype[]="NXFS"; /* see zi_short() */
static ZCONST char Far method[
{"Stored", "Shrunk", "Reduce1", "Reduce2", "Reduce3", "Reduce4",
"Implode", "Token", "Defl:#", "Def64#", "ImplDCL", "PKres11",
"BZip2", "Unk:###"};
The "Unk:###" is the one being used, and "#" is supposed to be replaced by the method number. Increasing "methbuf" size (eg: to 16 characters) fixes the buffer overflow.
For reference, this is where the buffer overflow really happens (around line 330):
methnum = MIN(G.crec.
if (methnum == DEFLATED || methnum == ENHDEFLATED) {
} else if (methnum >= NUM_METHODS) {
}
The last sprintf() only has space for 3 characters (and in fact uses %03u formatting string), but it does not take into account that compression_method is actually an unbounded 16-bit unsigned value.
CVE References
Changed in unzip (Ubuntu): | |
importance: | Undecided → Low |
information type: | Public → Public Security |
Thanks for this investigation! It looks like the overflow is not very harmful, so I'm unmarking this a security bug. A single byte overflow in the bss region is happening, which does not appear to be near any control structures.