Re: Gzip & segmentation faults

From: woschat_private
Date: Fri Dec 26 1997 - 20:09:09 PST

  • Next message: tl: "quake2 patch"

    =?UNKNOWN-8BIT?Q?Micha=B3?= Zalewski <lcamtufat_private> writes:
    > Few days ago, I noticed a problem(s) with gzip and it's archives.
    > Gzip seems to be poorly-written with regard to range checking, so
    > it's quite easy to cause segmentation faults and buffer overflows.
    > Simpliest ooverflow can be done by passing to gzip/gunzip filename
    > longer than 1024 bytes:
    >
    > $ gzip blahblahblahblah... [cut!]
    > Segmentation fault (core dumped).
    
    And here is a fix for the problem:
    
    Index: gzip.c
    ===================================================================
    RCS file: /usr/cvs/src/gnu/usr.bin/gzip/gzip.c,v
    retrieving revision 1.7
    diff -u -r1.7 gzip.c
    --- gzip.c      1997/03/15 22:43:58     1.7
    +++ gzip.c      1997/12/27 03:20:37
    @@ -1006,6 +1006,13 @@
         char *dot; /* pointer to ifname extension, or NULL */
     #endif
    
    +    if (strlen(iname) >= sizeof(ifname) - 3) {
    +       errno = ENAMETOOLONG;
    +       perror(iname);
    +       exit_code = ERROR;
    +       return ERROR;
    +    }
    +
         strcpy(ifname, iname);
    
         /* If input file exists, return OK. */
    
    
    
    > Attached example of 'evil' archive (Altered.gz) has been created by
    > compressing empty file with gzip's -n switch. After all, byte at offset
    > 0x0a (one of possibilities :) has been changed.
    > Under Linux, attempt of unziping or viewing this file will cause
    > nice segmentation fault. MS-DOS gzip screws-up totally.
    
    Index: inflate.c
    ===================================================================
    RCS file: /usr/cvs/src/gnu/usr.bin/gzip/inflate.c,v
    retrieving revision 1.6
    diff -u -r1.6 inflate.c
    --- inflate.c   1997/02/22 15:45:58     1.6
    +++ inflate.c   1997/12/26 20:21:39
    @@ -767,6 +767,8 @@
         return i;                   /* incomplete code set */
       }
    
    +  if (tl == NULL) /* Grrrhhh */
    +       return 2;
    
       /* read in literal and distance code lengths */
       n = nl + nd;
    
    
    --
    Wolfram Schneider   <woschat_private>   http://www.freebsd.org/~wosch/
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:37:39 PDT