components/unzip/patches/CVE-2014-8141.patch
branchs11u3-sru
changeset 5551 6d32c82eb4f5
parent 5545 4ba4c8209739
child 5552 4e17dd2a1b16
equal deleted inserted replaced
5545:4ba4c8209739 5551:6d32c82eb4f5
     1 Source:
       
     2 https://bugzilla.redhat.com/show_bug.cgi?id=1174856
       
     3 Info:
       
     4 http://www.ocert.org/advisories/ocert-2014-011.html
       
     5 
       
     6 --- a/process.c	2009-03-06 02:25:10.000000000 +0100
       
     7 +++ b/process.c	2014-12-05 22:42:39.000000000 +0100
       
     8 @@ -1,5 +1,5 @@
       
     9  /*
       
    10 -  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
       
    11 +  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
       
    12  
       
    13    See the accompanying file LICENSE, version 2009-Jan-02 or later
       
    14    (the contents of which are also included in unzip.h) for terms of use.
       
    15 @@ -1888,48 +1888,82 @@ int getZip64Data(__G__ ef_buf, ef_len)
       
    16      and a 4-byte version of disk start number.
       
    17      Sets both local header and central header fields.  Not terribly clever,
       
    18      but it means that this procedure is only called in one place.
       
    19 +
       
    20 +    2014-12-05 SMS.
       
    21 +    Added checks to ensure that enough data are available before calling
       
    22 +    makeint64() or makelong().  Replaced various sizeof() values with
       
    23 +    simple ("4" or "8") constants.  (The Zip64 structures do not depend
       
    24 +    on our variable sizes.)  Error handling is crude, but we should now
       
    25 +    stay within the buffer.
       
    26    ---------------------------------------------------------------------------*/
       
    27  
       
    28 +#define Z64FLGS 0xffff
       
    29 +#define Z64FLGL 0xffffffff
       
    30 +
       
    31      if (ef_len == 0 || ef_buf == NULL)
       
    32          return PK_COOL;
       
    33  
       
    34      Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
       
    35        ef_len));
       
    36  
       
    37 -    while (ef_len >= EB_HEADSIZE) {
       
    38 +    while (ef_len >= EB_HEADSIZE)
       
    39 +    {
       
    40          eb_id = makeword(EB_ID + ef_buf);
       
    41          eb_len = makeword(EB_LEN + ef_buf);
       
    42  
       
    43 -        if (eb_len > (ef_len - EB_HEADSIZE)) {
       
    44 -            /* discovered some extra field inconsistency! */
       
    45 +        if (eb_len > (ef_len - EB_HEADSIZE))
       
    46 +        {
       
    47 +            /* Extra block length exceeds remaining extra field length. */
       
    48              Trace((stderr,
       
    49                "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
       
    50                ef_len - EB_HEADSIZE));
       
    51              break;
       
    52          }
       
    53 -        if (eb_id == EF_PKSZ64) {
       
    54 -
       
    55 +        if (eb_id == EF_PKSZ64)
       
    56 +        {
       
    57            int offset = EB_HEADSIZE;
       
    58  
       
    59 -          if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
       
    60 -            G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
       
    61 -            offset += sizeof(G.crec.ucsize);
       
    62 +          if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
       
    63 +          {
       
    64 +            if (offset+ 8 > ef_len)
       
    65 +              return PK_ERR;
       
    66 +
       
    67 +            G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
       
    68 +            offset += 8;
       
    69            }
       
    70 -          if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
       
    71 -            G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
       
    72 -            offset += sizeof(G.crec.csize);
       
    73 +
       
    74 +          if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
       
    75 +          {
       
    76 +            if (offset+ 8 > ef_len)
       
    77 +              return PK_ERR;
       
    78 +
       
    79 +            G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
       
    80 +            offset += 8;
       
    81            }
       
    82 -          if (G.crec.relative_offset_local_header == 0xffffffff){
       
    83 +
       
    84 +          if (G.crec.relative_offset_local_header == Z64FLGL)
       
    85 +          {
       
    86 +            if (offset+ 8 > ef_len)
       
    87 +              return PK_ERR;
       
    88 +
       
    89              G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
       
    90 -            offset += sizeof(G.crec.relative_offset_local_header);
       
    91 +            offset += 8;
       
    92            }
       
    93 -          if (G.crec.disk_number_start == 0xffff){
       
    94 +
       
    95 +          if (G.crec.disk_number_start == Z64FLGS)
       
    96 +          {
       
    97 +            if (offset+ 4 > ef_len)
       
    98 +              return PK_ERR;
       
    99 +
       
   100              G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
       
   101 -            offset += sizeof(G.crec.disk_number_start);
       
   102 +            offset += 4;
       
   103            }
       
   104 +#if 0
       
   105 +          break;                /* Expect only one EF_PKSZ64 block. */
       
   106 +#endif /* 0 */
       
   107          }
       
   108  
       
   109 -        /* Skip this extra field block */
       
   110 +        /* Skip this extra field block. */
       
   111          ef_buf += (eb_len + EB_HEADSIZE);
       
   112          ef_len -= (eb_len + EB_HEADSIZE);
       
   113      }
       
   114 --- a/fileio.c	2009-04-20 02:03:44.000000000 +0200
       
   115 +++ b/fileio.c	2014-12-05 22:44:16.000000000 +0100
       
   116 @@ -176,6 +176,8 @@ static ZCONST char Far FilenameTooLongTr
       
   117  #endif
       
   118  static ZCONST char Far ExtraFieldTooLong[] =
       
   119    "warning:  extra field too long (%d).  Ignoring...\n";
       
   120 +static ZCONST char Far ExtraFieldCorrupt[] =
       
   121 +  "warning:  extra field (type: 0x%04x) corrupt.  Continuing...\n";
       
   122  
       
   123  #ifdef WINDLL
       
   124     static ZCONST char Far DiskFullQuery[] =
       
   125 @@ -2295,7 +2297,12 @@ int do_string(__G__ length, option)   /*
       
   126              if (readbuf(__G__ (char *)G.extra_field, length) == 0)
       
   127                  return PK_EOF;
       
   128              /* Looks like here is where extra fields are read */
       
   129 -            getZip64Data(__G__ G.extra_field, length);
       
   130 +            if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
       
   131 +            {
       
   132 +                Info(slide, 0x401, ((char *)slide,
       
   133 +                 LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
       
   134 +                error = PK_WARN;
       
   135 +            }
       
   136  #ifdef UNICODE_SUPPORT
       
   137              G.unipath_filename = NULL;
       
   138              if (G.UzO.U_flag < 2) {