Bug 62932 (CVE-2004-1010)

Summary: VUL-0: CVE-2004-1010: Buffer overflow in zip filename handling
Product: [Novell Products] SUSE Security Incidents Reporter: Marcus Meissner <meissner>
Component: IncidentsAssignee: Security Team bot <security-team>
Status: RESOLVED FIXED QA Contact: Security Team bot <security-team>
Severity: Major    
Priority: P3 - Medium CC: heiko.rommel, lnussel, security-team
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Whiteboard: CVE-2004-1010: CVSS v2 Base Score: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Ludwig Nussel 2004-11-04 18:40:05 UTC
We received the following report via full-disclosure.
The issue is public.

Date: Wed, 3 Nov 2004 15:11:29 -0800
From: vuln@hexview.com
To: bugtraq@securityfocus.com, full-disclosure@lists.netsys.com
Subject: [Full-Disclosure] [HV-MED] Zip/Linux long path buffer overflow

Zip/Linux long path buffer overflow

Classification:
===============
Level: low-[MED]-high-crit
ID: HEXVIEW*2004*11*03*1
URL: http://www.hexview.com/docs/20041103-1.txt

Overview:
=========
Zip console application by Info-Zip (http://www.info-zip.org) is an
open-source software and part of many Linux distributions.
A buffer overflow condition can be triggered and exploited during
recursive compression operation.

Affected products:
==================
HexView tested the issue using Zip 2.3 which comes as "zip" package
with Debian Linux. Possibly all earlier Info-Zip versions are vulnerable.
Info-Zip applications for other operating systems are also vulnerable,
but depending on operating system and file system restrictions, the
vulnerability may or may not be triggered or exploited.

Cause and Effect:
=================
When zip performs recursive folder compression, it does not check
for the length of resulting path. If the path is too long, a buffer
overflow occurs leading to stack corruption and segmentation fault.
It is possible to exploit this vulnerability by embedding a shellcode
in directory or file name. While the issue is not of primary concern
for regular users, it can be critical for environments where zip archives
are re-compressed automatically using Info-Zip application.

Demonstration:
==============
The issue can be reproduced by following these steps:
1. Create an 8-level directory structure, where each directory name is
   256 characters long (we used 256 'a' characters).
2. run "zip -r file.zip *". The application will crash with
    "segmentation fault"
3. run "gdb -core core `which zip`" (assuming core drop is enabled)
4. type "where" and hit Enter. Here is what you'll see:

Program terminated with signal 11, Segmentation fault.
[garbage truncated]
#0  0x0805108e in error ()
#1  0x61616161 in ?? ()
#2  0x61616161 in ?? ()
#3  0x61616161 in ?? ()


Vendor Status:
==============
HexView tried to notify vendor using vendor-provided e-mail address
(zip-bugs@lists.wku.edu) on 2004-10-03. The mail was returned back 
as undeliverable.

About HexView:
==============
HexView contributes to online security-related lists for almost a
decade. The scope of our expertize spreads over Windows, Linux, Sun,
MacOS platforms, network applications, and embedded devices. The chances
are you read our advisories or disclosures. For more information visit
http://www.hexview.com

Distribution:
=============
This document may be freely distributed through any channels as long as
the contents are kept unmodified. Commercial use of the information in
the document is not allowed without written permission from HexView
signed by our pgp key.

HexView Disclosure Policy:
==========================
HexView notifies vendors that have publicly available contact e-mail 24
hours before disclosing any information to the public. If we are unable
to find vendor's e-mail address or if no reply is received within 24
hours, HexView will publish vulnerability notification including all
technical details unless the issue is rated as "critical". If vendor
does not reply within 72 hours, HexView may disclose all details for
critical vulnerabilities as well.

If vendor replies within the above mentioned time period, HexView will
announce the vulnerability, but will not disclose the details required
to reproduce it. HexView will also specify the date when full disclosure
containing all the details will be published. The time period between
announcement and full disclosure is 30 days unless there is an agreement
with vendor and appropriate justification for extension. If vendor
resolves the issue earlier than 30 days after announcement, HexView will
publish full disclosure as soon as the fix is available to the public.

HexView also reserves the right to publish any detail of any
vulnerability at any time.

Feedback and comments:
======================
Feedback and questions about this disclosure are welcome at
vtalk@hexview.com

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html
Comment 1 Ludwig Nussel 2004-11-08 17:54:19 UTC
* This comment was added by mail.
----- Forwarded message from Josh Bressers <bressers@redhat.com> -----

Date: Fri, 5 Nov 2004 16:00:58 -0500
From: Josh Bressers <bressers@redhat.com>
To: martin.pitt@canonical.com
Cc: full-disclosure@lists.netsys.com, bugtraq@securityfocus.com
Subject: Re: [Full-Disclosure] [HV-MED] Zip/Linux long path buffer overflow

On Fri, Nov 05, 2004 at 02:26:33PM +0100, Martin Pitt wrote:
| I prepared a small fix for this (see below). It does not make zip work
| with long file names, but at least it exits cleanly with giving the
| reason, and does not segfault.

This fix will allow zip to create an archive with very long filenames.

I'm also changing the type of len from a signed int to size_t to prevent
trouble in the future.

--- zip-2.3/unix/unix.c.orig    2004-11-05 15:44:41.000000000 -0500
+++ zip-2.3/unix/unix.c 2004-11-05 15:50:28.000000000 -0500
    a file size of -1 */
 {
   struct stat s;        /* results of stat() */
-  char name[FNMAX];
-  int len = strlen(f);
+  char *name;
+  size_t len = strlen(f);
 
   if (f == label) {
     if (a != NULL)
       t->atime = t->mtime = t->ctime = label_utim;
     return label_time;
   }
+
+  name = malloc(len+1);
+  if (!name)
+    return 0;
+
   strcpy(name, f);
   if (name[len - 1] == '/')
     name[len - 1] = '\0';
Comment 2 Sebastian Krahmer 2004-11-08 18:02:50 UTC
Does the fix apply?
Shall I make patchinfo files?
Comment 3 Ludwig Nussel 2004-11-09 17:10:27 UTC
CAN-2004-1010 
Comment 4 Heiko Rommel 2004-11-10 03:10:16 UTC
The patch applies and compiles both on SLES8 and SLES9.
Please provide patchinfos.

For testing it I would like to have a way to create a directory with 256
characters in bash. But regardless of the file system (reiser, ext2 or ext3),
mkdir won't let me because the "file name is too long".

What's the trick ? Or I have to use C for that ?

I used something like:

DIRNAME=$(perl -e ' print "a" x 256 ; ')
moonraker:~ # mkdir $DIRNAME
mkdir: cannot create directory
`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa':
File name too long
Comment 5 Ludwig Nussel 2004-11-10 22:13:05 UTC
A file name can be max 255 characters but a path can have max 4096 characters.   
Try this: 
 
perl -e '$i=10;while($i){$fn="x"x255;mkdir $fn; chdir$fn;--$i}' 
Comment 6 Heiko Rommel 2004-11-11 18:17:02 UTC
Got it ;)

Please provide patchinfos.
Comment 7 Heiko Rommel 2004-11-12 19:50:29 UTC
Fixed and commited to all of is_maintained and is_maintained -b (including
patchinfos).
Comment 8 Marcus Meissner 2004-11-12 20:07:07 UTC
<!-- SBZ_reopen -->Reopened by meissner@suse.de at Fri Nov 12 13:07:07 2004, took initial reporter lnussel@suse.de to cc
Comment 9 Marcus Meissner 2004-11-12 20:07:07 UTC
reopen for tracking 
Comment 10 Marcus Meissner 2004-11-12 20:12:48 UTC
swamp_id: 22 
Comment 11 Michael Schröder 2004-11-16 01:43:09 UTC
Hmm, the patch contains a malloc but no free. Looks like a memory leak.
Please fix.
Comment 12 Michael Schröder 2004-11-22 23:10:55 UTC
Hello? Nobody listening?
Comment 13 Thomas Biege 2004-11-23 16:09:11 UTC
thomas@bragg:~> tel rommel 
------------------------------------------------------------ 
Name       : Heiko Rommel 
Login      : rommel 
Phone      : +49-911-740 53 - 696 
Mobile     : 0179 5977 815 
Department : [RD-QA] Quality Assurance 
Position   : Employee 
Location   : Maxtorhof, Room 2.2.10 
Tasks      : DNS, News and Mail 
             mailing lists 
             SLOX based groupware/GW migration 
             IT documentation 
             print server 
             a few packages from the distribution (mainly mail/news stuff) 
Absent     : Mon 2004-11-15 - Fri 2004-11-19 
             Wed 2004-12-22 - Fri 2004-12-31 
             Fri 2004-12-24 
             Fri 2004-12-31 
------------------------------------------------------------ 
 
Heiko was away last week. 
 
Comment 14 Michael Schröder 2004-11-30 02:16:28 UTC
Still nobody listening?
Comment 15 Thomas Biege 2004-11-30 18:14:49 UTC
Date: Tue, 30 Nov 2004 11:12:32 +0100 
From: rommel@suse.de 
To: thomas@suse.de 
Subject: Re: Bug 62932 
Auto-Submitted: auto-replied (vacation) 
 
I'm out of the office until 2004/12/1. 
 
- 
 
Ich bin bis einschliesslich 1.12.2004 abwesend. 
Comment 16 Heiko Rommel 2004-12-02 18:23:38 UTC
Sorry, for the trouble my absence is causing these days.
If not already done, I'm going to start to work on it at 14:00 today.
Comment 17 Heiko Rommel 2004-12-02 21:56:21 UTC
Reworked the patch. Starting to re-commit at 16:00 CET.

--- unix/unix.c
+++ unix/unix.c
@@ -324,8 +324,9 @@
    a file size of -1 */
 {
   struct stat s;        /* results of stat() */
-  char name[FNMAX];
-  int len = strlen(f);
+  char *name;
+  size_t len = strlen(f);
+
 
   if (f == label) {
     if (a != NULL)
@@ -336,19 +337,30 @@
       t->atime = t->mtime = t->ctime = label_utim;
     return label_time;
   }
+
+  name = malloc(len+1);
+  if (!name)
+    return 0;
+
   strcpy(name, f);
   if (name[len - 1] == '/')
     name[len - 1] = '\0';
   /* not all systems allow stat'ing a file with / appended */
   if (strcmp(f, "-") == 0) {
-    if (fstat(fileno(stdin), &s) != 0)
+    if (fstat(fileno(stdin), &s) != 0) {
+      free(name);
       error("fstat(stdin)");
+    }
   }
-  else if (LSSTAT(name, &s) != 0)
+  else if (LSSTAT(name, &s) != 0) {
     /* Accept about any file kind including directories
      * (stored with trailing / with -r option)
      */
+    free(name);
     return 0;
+  }
+
+  free(name);
 
   if (a != NULL) {
 #ifndef OS390
Comment 18 Heiko Rommel 2004-12-03 00:41:23 UTC
Fixed in STABLE is_maintained.
Comment 19 Marcus Meissner 2004-12-03 18:52:41 UTC
<!-- SBZ_reopen -->Reopened by meissner@suse.de at Fri Dec  3 11:52:41 2004
Comment 20 Marcus Meissner 2004-12-03 18:52:41 UTC
reopen for tracking 
Comment 21 Marcus Meissner 2004-12-06 21:55:45 UTC
patchinfos checked in now. 
Comment 22 Thomas Biege 2004-12-07 17:17:56 UTC
packages approved. 
Comment 23 Thomas Biege 2009-10-13 19:58:33 UTC
CVE-2004-1010: CVSS v2 Base Score: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)