zlib: patch for CVE-2016-9840, CVE-2016-9841, CVE-9842, CVE-9843
This commit is contained in:
parent
b0a1028a1a
commit
41f55691a9
71
pkgs/development/libraries/zlib/CVE-2016-9840.patch
Normal file
71
pkgs/development/libraries/zlib/CVE-2016-9840.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From 6a043145ca6e9c55184013841a67b2fef87e44c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Adler <madler@alumni.caltech.edu>
|
||||||
|
Date: Wed, 21 Sep 2016 23:35:50 -0700
|
||||||
|
Subject: [PATCH] Remove offset pointer optimization in inftrees.c.
|
||||||
|
|
||||||
|
inftrees.c was subtracting an offset from a pointer to an array,
|
||||||
|
in order to provide a pointer that allowed indexing starting at
|
||||||
|
the offset. This is not compliant with the C standard, for which
|
||||||
|
the behavior of a pointer decremented before its allocated memory
|
||||||
|
is undefined. Per the recommendation of a security audit of the
|
||||||
|
zlib code by Trail of Bits and TrustInSoft, in support of the
|
||||||
|
Mozilla Foundation, this tiny optimization was removed, in order
|
||||||
|
to avoid the possibility of undefined behavior.
|
||||||
|
---
|
||||||
|
inftrees.c | 18 ++++++++----------
|
||||||
|
1 file changed, 8 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/inftrees.c b/inftrees.c
|
||||||
|
index 22fcd66..0d2670d 100644
|
||||||
|
--- a/inftrees.c
|
||||||
|
+++ b/inftrees.c
|
||||||
|
@@ -54,7 +54,7 @@ unsigned short FAR *work;
|
||||||
|
code FAR *next; /* next available space in table */
|
||||||
|
const unsigned short FAR *base; /* base value table to use */
|
||||||
|
const unsigned short FAR *extra; /* extra bits table to use */
|
||||||
|
- int end; /* use base and extra for symbol > end */
|
||||||
|
+ unsigned match; /* use base and extra for symbol >= match */
|
||||||
|
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||||
|
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||||
|
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||||
|
@@ -181,19 +181,17 @@ unsigned short FAR *work;
|
||||||
|
switch (type) {
|
||||||
|
case CODES:
|
||||||
|
base = extra = work; /* dummy value--not used */
|
||||||
|
- end = 19;
|
||||||
|
+ match = 20;
|
||||||
|
break;
|
||||||
|
case LENS:
|
||||||
|
base = lbase;
|
||||||
|
- base -= 257;
|
||||||
|
extra = lext;
|
||||||
|
- extra -= 257;
|
||||||
|
- end = 256;
|
||||||
|
+ match = 257;
|
||||||
|
break;
|
||||||
|
default: /* DISTS */
|
||||||
|
base = dbase;
|
||||||
|
extra = dext;
|
||||||
|
- end = -1;
|
||||||
|
+ match = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize state for loop */
|
||||||
|
@@ -216,13 +214,13 @@ unsigned short FAR *work;
|
||||||
|
for (;;) {
|
||||||
|
/* create table entry */
|
||||||
|
here.bits = (unsigned char)(len - drop);
|
||||||
|
- if ((int)(work[sym]) < end) {
|
||||||
|
+ if (work[sym] + 1 < match) {
|
||||||
|
here.op = (unsigned char)0;
|
||||||
|
here.val = work[sym];
|
||||||
|
}
|
||||||
|
- else if ((int)(work[sym]) > end) {
|
||||||
|
- here.op = (unsigned char)(extra[work[sym]]);
|
||||||
|
- here.val = base[work[sym]];
|
||||||
|
+ else if (work[sym] >= match) {
|
||||||
|
+ here.op = (unsigned char)(extra[work[sym] - match]);
|
||||||
|
+ here.val = base[work[sym] - match];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
here.op = (unsigned char)(32 + 64); /* end of block */
|
224
pkgs/development/libraries/zlib/CVE-2016-9841.patch
Normal file
224
pkgs/development/libraries/zlib/CVE-2016-9841.patch
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
From 9aaec95e82117c1cb0f9624264c3618fc380cecb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Adler <madler@alumni.caltech.edu>
|
||||||
|
Date: Wed, 21 Sep 2016 22:25:21 -0700
|
||||||
|
Subject: [PATCH] Use post-increment only in inffast.c.
|
||||||
|
|
||||||
|
An old inffast.c optimization turns out to not be optimal anymore
|
||||||
|
with modern compilers, and furthermore was not compliant with the
|
||||||
|
C standard, for which decrementing a pointer before its allocated
|
||||||
|
memory is undefined. Per the recommendation of a security audit of
|
||||||
|
the zlib code by Trail of Bits and TrustInSoft, in support of the
|
||||||
|
Mozilla Foundation, this "optimization" was removed, in order to
|
||||||
|
avoid the possibility of undefined behavior.
|
||||||
|
---
|
||||||
|
inffast.c | 81 ++++++++++++++++++++++++---------------------------------------
|
||||||
|
1 file changed, 31 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/inffast.c b/inffast.c
|
||||||
|
index bda59ce..f0d163d 100644
|
||||||
|
--- a/inffast.c
|
||||||
|
+++ b/inffast.c
|
||||||
|
@@ -10,25 +10,6 @@
|
||||||
|
|
||||||
|
#ifndef ASMINF
|
||||||
|
|
||||||
|
-/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||||
|
- Based on testing to date,
|
||||||
|
- Pre-increment preferred for:
|
||||||
|
- - PowerPC G3 (Adler)
|
||||||
|
- - MIPS R5000 (Randers-Pehrson)
|
||||||
|
- Post-increment preferred for:
|
||||||
|
- - none
|
||||||
|
- No measurable difference:
|
||||||
|
- - Pentium III (Anderson)
|
||||||
|
- - M68060 (Nikl)
|
||||||
|
- */
|
||||||
|
-#ifdef POSTINC
|
||||||
|
-# define OFF 0
|
||||||
|
-# define PUP(a) *(a)++
|
||||||
|
-#else
|
||||||
|
-# define OFF 1
|
||||||
|
-# define PUP(a) *++(a)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
Decode literal, length, and distance codes and write out the resulting
|
||||||
|
literal and match bytes until either not enough input or output is
|
||||||
|
@@ -96,9 +77,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
|
||||||
|
/* copy state to local variables */
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
- in = strm->next_in - OFF;
|
||||||
|
+ in = strm->next_in;
|
||||||
|
last = in + (strm->avail_in - 5);
|
||||||
|
- out = strm->next_out - OFF;
|
||||||
|
+ out = strm->next_out;
|
||||||
|
beg = out - (start - strm->avail_out);
|
||||||
|
end = out + (strm->avail_out - 257);
|
||||||
|
#ifdef INFLATE_STRICT
|
||||||
|
@@ -119,9 +100,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
input data or output space */
|
||||||
|
do {
|
||||||
|
if (bits < 15) {
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
}
|
||||||
|
here = lcode[hold & lmask];
|
||||||
|
@@ -134,14 +115,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||||
|
"inflate: literal '%c'\n" :
|
||||||
|
"inflate: literal 0x%02x\n", here.val));
|
||||||
|
- PUP(out) = (unsigned char)(here.val);
|
||||||
|
+ *out++ = (unsigned char)(here.val);
|
||||||
|
}
|
||||||
|
else if (op & 16) { /* length base */
|
||||||
|
len = (unsigned)(here.val);
|
||||||
|
op &= 15; /* number of extra bits */
|
||||||
|
if (op) {
|
||||||
|
if (bits < op) {
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
}
|
||||||
|
len += (unsigned)hold & ((1U << op) - 1);
|
||||||
|
@@ -150,9 +131,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
}
|
||||||
|
Tracevv((stderr, "inflate: length %u\n", len));
|
||||||
|
if (bits < 15) {
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
}
|
||||||
|
here = dcode[hold & dmask];
|
||||||
|
@@ -165,10 +146,10 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
dist = (unsigned)(here.val);
|
||||||
|
op &= 15; /* number of extra bits */
|
||||||
|
if (bits < op) {
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
if (bits < op) {
|
||||||
|
- hold += (unsigned long)(PUP(in)) << bits;
|
||||||
|
+ hold += (unsigned long)(*in++) << bits;
|
||||||
|
bits += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -196,30 +177,30 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||||
|
if (len <= op - whave) {
|
||||||
|
do {
|
||||||
|
- PUP(out) = 0;
|
||||||
|
+ *out++ = 0;
|
||||||
|
} while (--len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len -= op - whave;
|
||||||
|
do {
|
||||||
|
- PUP(out) = 0;
|
||||||
|
+ *out++ = 0;
|
||||||
|
} while (--op > whave);
|
||||||
|
if (op == 0) {
|
||||||
|
from = out - dist;
|
||||||
|
do {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
} while (--len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
- from = window - OFF;
|
||||||
|
+ from = window;
|
||||||
|
if (wnext == 0) { /* very common case */
|
||||||
|
from += wsize - op;
|
||||||
|
if (op < len) { /* some from window */
|
||||||
|
len -= op;
|
||||||
|
do {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
} while (--op);
|
||||||
|
from = out - dist; /* rest from output */
|
||||||
|
}
|
||||||
|
@@ -230,14 +211,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
if (op < len) { /* some from end of window */
|
||||||
|
len -= op;
|
||||||
|
do {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
} while (--op);
|
||||||
|
- from = window - OFF;
|
||||||
|
+ from = window;
|
||||||
|
if (wnext < len) { /* some from start of window */
|
||||||
|
op = wnext;
|
||||||
|
len -= op;
|
||||||
|
do {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
} while (--op);
|
||||||
|
from = out - dist; /* rest from output */
|
||||||
|
}
|
||||||
|
@@ -248,35 +229,35 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
if (op < len) { /* some from window */
|
||||||
|
len -= op;
|
||||||
|
do {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
} while (--op);
|
||||||
|
from = out - dist; /* rest from output */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (len > 2) {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
+ *out++ = *from++;
|
||||||
|
+ *out++ = *from++;
|
||||||
|
len -= 3;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
if (len > 1)
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
from = out - dist; /* copy direct from output */
|
||||||
|
do { /* minimum length is three */
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
+ *out++ = *from++;
|
||||||
|
+ *out++ = *from++;
|
||||||
|
len -= 3;
|
||||||
|
} while (len > 2);
|
||||||
|
if (len) {
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
if (len > 1)
|
||||||
|
- PUP(out) = PUP(from);
|
||||||
|
+ *out++ = *from++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -313,8 +294,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
|
hold &= (1U << bits) - 1;
|
||||||
|
|
||||||
|
/* update state and return */
|
||||||
|
- strm->next_in = in + OFF;
|
||||||
|
- strm->next_out = out + OFF;
|
||||||
|
+ strm->next_in = in;
|
||||||
|
+ strm->next_out = out;
|
||||||
|
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||||
|
strm->avail_out = (unsigned)(out < end ?
|
||||||
|
257 + (end - out) : 257 - (out - end));
|
29
pkgs/development/libraries/zlib/CVE-2016-9842.patch
Normal file
29
pkgs/development/libraries/zlib/CVE-2016-9842.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From e54e1299404101a5a9d0cf5e45512b543967f958 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Adler <madler@alumni.caltech.edu>
|
||||||
|
Date: Sat, 5 Sep 2015 17:45:55 -0700
|
||||||
|
Subject: [PATCH] Avoid shifts of negative values inflateMark().
|
||||||
|
|
||||||
|
The C standard says that bit shifts of negative integers is
|
||||||
|
undefined. This casts to unsigned values to assure a known
|
||||||
|
result.
|
||||||
|
---
|
||||||
|
inflate.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/inflate.c b/inflate.c
|
||||||
|
index 2889e3a..a718416 100644
|
||||||
|
--- a/inflate.c
|
||||||
|
+++ b/inflate.c
|
||||||
|
@@ -1506,9 +1506,10 @@ z_streamp strm;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
|
||||||
|
- if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
|
||||||
|
+ if (strm == Z_NULL || strm->state == Z_NULL)
|
||||||
|
+ return (long)(((unsigned long)0 - 1) << 16);
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
- return ((long)(state->back) << 16) +
|
||||||
|
+ return (long)(((unsigned long)((long)state->back)) << 16) +
|
||||||
|
(state->mode == COPY ? state->length :
|
||||||
|
(state->mode == MATCH ? state->was - state->length : 0));
|
||||||
|
}
|
49
pkgs/development/libraries/zlib/CVE-2016-9843.patch
Normal file
49
pkgs/development/libraries/zlib/CVE-2016-9843.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From d1d577490c15a0c6862473d7576352a9f18ef811 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Adler <madler@alumni.caltech.edu>
|
||||||
|
Date: Wed, 28 Sep 2016 20:20:25 -0700
|
||||||
|
Subject: [PATCH] Avoid pre-decrement of pointer in big-endian CRC calculation.
|
||||||
|
|
||||||
|
There was a small optimization for PowerPCs to pre-increment a
|
||||||
|
pointer when accessing a word, instead of post-incrementing. This
|
||||||
|
required prefacing the loop with a decrement of the pointer,
|
||||||
|
possibly pointing before the object passed. This is not compliant
|
||||||
|
with the C standard, for which decrementing a pointer before its
|
||||||
|
allocated memory is undefined. When tested on a modern PowerPC
|
||||||
|
with a modern compiler, the optimization no longer has any effect.
|
||||||
|
Due to all that, and per the recommendation of a security audit of
|
||||||
|
the zlib code by Trail of Bits and TrustInSoft, in support of the
|
||||||
|
Mozilla Foundation, this "optimization" was removed, in order to
|
||||||
|
avoid the possibility of undefined behavior.
|
||||||
|
---
|
||||||
|
crc32.c | 4 +---
|
||||||
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/crc32.c b/crc32.c
|
||||||
|
index 979a719..05733f4 100644
|
||||||
|
--- a/crc32.c
|
||||||
|
+++ b/crc32.c
|
||||||
|
@@ -278,7 +278,7 @@ local unsigned long crc32_little(crc, buf, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
-#define DOBIG4 c ^= *++buf4; \
|
||||||
|
+#define DOBIG4 c ^= *buf4++; \
|
||||||
|
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
|
||||||
|
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
|
||||||
|
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
|
||||||
|
@@ -300,7 +300,6 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||||
|
- buf4--;
|
||||||
|
while (len >= 32) {
|
||||||
|
DOBIG32;
|
||||||
|
len -= 32;
|
||||||
|
@@ -309,7 +308,6 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
|
DOBIG4;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
- buf4++;
|
||||||
|
buf = (const unsigned char FAR *)buf4;
|
||||||
|
|
||||||
|
if (len) do {
|
@ -13,6 +13,13 @@ stdenv.mkDerivation rec {
|
|||||||
sha256 = "039agw5rqvqny92cpkrfn243x2gd4xn13hs3xi6isk55d2vqqr9n";
|
sha256 = "039agw5rqvqny92cpkrfn243x2gd4xn13hs3xi6isk55d2vqqr9n";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./CVE-2016-9840.patch
|
||||||
|
./CVE-2016-9841.patch
|
||||||
|
./CVE-2016-9842.patch
|
||||||
|
./CVE-2016-9843.patch
|
||||||
|
];
|
||||||
|
|
||||||
postPatch = stdenv.lib.optionalString stdenv.isDarwin ''
|
postPatch = stdenv.lib.optionalString stdenv.isDarwin ''
|
||||||
substituteInPlace configure \
|
substituteInPlace configure \
|
||||||
--replace '/usr/bin/libtool' 'ar' \
|
--replace '/usr/bin/libtool' 'ar' \
|
||||||
@ -81,4 +88,3 @@ stdenv.mkDerivation rec {
|
|||||||
platforms = platforms.all;
|
platforms = platforms.all;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user