| 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. |
| |
| CVE: CVE-2016-9843 |
| Upstream-Status: Backport |
| Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| --- |
| crc32.c | 4 +--- |
| 1 file changed, 1 insertion(+), 3 deletions(-) |
| |
| diff --git a/zlib/crc32.c b/zlib/crc32.c |
| index 979a7190..05733f4e 100644 |
| --- a/zlib/crc32.c |
| +++ b/zlib/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 { |