all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob 283925fc345118b5852dc9797bbae42c634358c4 4922 bytes (raw)
name: packages/patches/unzip-CVE-2014-8141.patch 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
From: sms
Subject: Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data()
Bug-Debian: http://bugs.debian.org/773722

--- a/fileio.c
+++ b/fileio.c
@@ -176,6 +176,8 @@
 #endif
 static ZCONST char Far ExtraFieldTooLong[] =
   "warning:  extra field too long (%d).  Ignoring...\n";
+static ZCONST char Far ExtraFieldCorrupt[] =
+  "warning:  extra field (type: 0x%04x) corrupt.  Continuing...\n";
 
 #ifdef WINDLL
    static ZCONST char Far DiskFullQuery[] =
@@ -2295,7 +2297,12 @@
             if (readbuf(__G__ (char *)G.extra_field, length) == 0)
                 return PK_EOF;
             /* Looks like here is where extra fields are read */
-            getZip64Data(__G__ G.extra_field, length);
+            if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
+            {
+                Info(slide, 0x401, ((char *)slide,
+                 LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
+                error = PK_WARN;
+            }
 #ifdef UNICODE_SUPPORT
             G.unipath_filename = NULL;
             if (G.UzO.U_flag < 2) {
--- a/process.c
+++ b/process.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2014 Info-ZIP.  All rights reserved.
 
   See the accompanying file LICENSE, version 2009-Jan-02 or later
   (the contents of which are also included in unzip.h) for terms of use.
@@ -1901,48 +1901,82 @@
     and a 4-byte version of disk start number.
     Sets both local header and central header fields.  Not terribly clever,
     but it means that this procedure is only called in one place.
+
+    2014-12-05 SMS.
+    Added checks to ensure that enough data are available before calling
+    makeint64() or makelong().  Replaced various sizeof() values with
+    simple ("4" or "8") constants.  (The Zip64 structures do not depend
+    on our variable sizes.)  Error handling is crude, but we should now
+    stay within the buffer.
   ---------------------------------------------------------------------------*/
 
+#define Z64FLGS 0xffff
+#define Z64FLGL 0xffffffff
+
     if (ef_len == 0 || ef_buf == NULL)
         return PK_COOL;
 
     Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
       ef_len));
 
-    while (ef_len >= EB_HEADSIZE) {
+    while (ef_len >= EB_HEADSIZE)
+    {
         eb_id = makeword(EB_ID + ef_buf);
         eb_len = makeword(EB_LEN + ef_buf);
 
-        if (eb_len > (ef_len - EB_HEADSIZE)) {
-            /* discovered some extra field inconsistency! */
+        if (eb_len > (ef_len - EB_HEADSIZE))
+        {
+            /* Extra block length exceeds remaining extra field length. */
             Trace((stderr,
               "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
               ef_len - EB_HEADSIZE));
             break;
         }
-        if (eb_id == EF_PKSZ64) {
-
+        if (eb_id == EF_PKSZ64)
+        {
           int offset = EB_HEADSIZE;
 
-          if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
-            G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.ucsize);
+          if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
+            offset += 8;
           }
-          if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
-            G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.csize);
+
+          if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
+            offset += 8;
           }
-          if (G.crec.relative_offset_local_header == 0xffffffff){
+
+          if (G.crec.relative_offset_local_header == Z64FLGL)
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
             G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.relative_offset_local_header);
+            offset += 8;
           }
-          if (G.crec.disk_number_start == 0xffff){
+
+          if (G.crec.disk_number_start == Z64FLGS)
+          {
+            if (offset+ 4 > ef_len)
+              return PK_ERR;
+
             G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
-            offset += sizeof(G.crec.disk_number_start);
+            offset += 4;
           }
+#if 0
+          break;                /* Expect only one EF_PKSZ64 block. */
+#endif /* 0 */
         }
 
-        /* Skip this extra field block */
+        /* Skip this extra field block. */
         ef_buf += (eb_len + EB_HEADSIZE);
         ef_len -= (eb_len + EB_HEADSIZE);
     }

debug log:

solving 283925fc345118b5852dc9797bbae42c634358c4 ...
found 283925fc345118b5852dc9797bbae42c634358c4 in https://git.savannah.gnu.org/cgit/guix.git

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.