Brad Bishop | 96ff198 | 2019-08-19 13:50:42 -0400 | [diff] [blame] | 1 | From d1d577490c15a0c6862473d7576352a9f18ef811 Mon Sep 17 00:00:00 2001 |
| 2 | From: Mark Adler <madler@alumni.caltech.edu> |
| 3 | Date: Wed, 28 Sep 2016 20:20:25 -0700 |
| 4 | Subject: [PATCH] Avoid pre-decrement of pointer in big-endian CRC calculation. |
| 5 | |
| 6 | There was a small optimization for PowerPCs to pre-increment a |
| 7 | pointer when accessing a word, instead of post-incrementing. This |
| 8 | required prefacing the loop with a decrement of the pointer, |
| 9 | possibly pointing before the object passed. This is not compliant |
| 10 | with the C standard, for which decrementing a pointer before its |
| 11 | allocated memory is undefined. When tested on a modern PowerPC |
| 12 | with a modern compiler, the optimization no longer has any effect. |
| 13 | Due to all that, and per the recommendation of a security audit of |
| 14 | the zlib code by Trail of Bits and TrustInSoft, in support of the |
| 15 | Mozilla Foundation, this "optimization" was removed, in order to |
| 16 | avoid the possibility of undefined behavior. |
| 17 | |
| 18 | CVE: CVE-2016-9843 |
| 19 | Upstream-Status: Backport |
| 20 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| 21 | --- |
| 22 | crc32.c | 4 +--- |
| 23 | 1 file changed, 1 insertion(+), 3 deletions(-) |
| 24 | |
| 25 | diff --git a/zlib/crc32.c b/zlib/crc32.c |
| 26 | index 979a7190..05733f4e 100644 |
| 27 | --- a/zlib/crc32.c |
| 28 | +++ b/zlib/crc32.c |
| 29 | @@ -278,7 +278,7 @@ local unsigned long crc32_little(crc, buf, len) |
| 30 | } |
| 31 | |
| 32 | /* ========================================================================= */ |
| 33 | -#define DOBIG4 c ^= *++buf4; \ |
| 34 | +#define DOBIG4 c ^= *buf4++; \ |
| 35 | c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ |
| 36 | crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] |
| 37 | #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 |
| 38 | @@ -300,7 +300,6 @@ local unsigned long crc32_big(crc, buf, len) |
| 39 | } |
| 40 | |
| 41 | buf4 = (const z_crc_t FAR *)(const void FAR *)buf; |
| 42 | - buf4--; |
| 43 | while (len >= 32) { |
| 44 | DOBIG32; |
| 45 | len -= 32; |
| 46 | @@ -309,7 +308,6 @@ local unsigned long crc32_big(crc, buf, len) |
| 47 | DOBIG4; |
| 48 | len -= 4; |
| 49 | } |
| 50 | - buf4++; |
| 51 | buf = (const unsigned char FAR *)buf4; |
| 52 | |
| 53 | if (len) do { |