Commit | Line | Data |
---|---|---|
453e101f MW |
1 | Fix CVE-2020-29385. Note that we omit the binary test file |
2 | tests/test-images/fail/hang_114.gif from the following commit, to avoid | |
3 | requiring 'git' to apply the patch. | |
4 | ||
5 | ||
6 | From bdd3acbd48a575d418ba6bf1b32d7bda2fae1c81 Mon Sep 17 00:00:00 2001 | |
7 | From: Robert Ancell <robert.ancell@canonical.com> | |
8 | Date: Mon, 30 Nov 2020 12:26:12 +1300 | |
9 | Subject: [PATCH] gif: Fix LZW decoder accepting invalid LZW code. | |
10 | ||
11 | The code value after a reset wasn't being validated, which means we would | |
12 | accept invalid codes. This could cause an infinite loop in the decoder. | |
13 | ||
14 | Fixes CVE-2020-29385 | |
15 | ||
16 | Fixes https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/164 | |
17 | --- | |
18 | gdk-pixbuf/lzw.c | 13 +++++++------ | |
19 | tests/test-images/fail/hang_114.gif | Bin 0 -> 5561 bytes | |
20 | 2 files changed, 7 insertions(+), 6 deletions(-) | |
21 | create mode 100644 tests/test-images/fail/hang_114.gif | |
22 | ||
23 | diff --git a/gdk-pixbuf/lzw.c b/gdk-pixbuf/lzw.c | |
24 | index 9e052a6f7..105daf2b1 100644 | |
25 | --- a/gdk-pixbuf/lzw.c | |
26 | +++ b/gdk-pixbuf/lzw.c | |
27 | @@ -195,19 +195,20 @@ lzw_decoder_feed (LZWDecoder *self, | |
28 | if (self->last_code != self->clear_code && self->code_table_size < MAX_CODES) { | |
29 | if (self->code < self->code_table_size) | |
30 | add_code (self, self->code); | |
31 | - else if (self->code == self->code_table_size) | |
32 | + else | |
33 | add_code (self, self->last_code); | |
34 | - else { | |
35 | - /* Invalid code received - just stop here */ | |
36 | - self->last_code = self->eoi_code; | |
37 | - return output_length; | |
38 | - } | |
39 | ||
40 | /* When table is full increase code size */ | |
41 | if (self->code_table_size == (1 << self->code_size) && self->code_size < LZW_CODE_MAX) | |
42 | self->code_size++; | |
43 | } | |
44 | ||
45 | + /* Invalid code received - just stop here */ | |
46 | + if (self->code >= self->code_table_size) { | |
47 | + self->last_code = self->eoi_code; | |
48 | + return output_length; | |
49 | + } | |
50 | + | |
51 | /* Convert codeword into indexes */ | |
52 | n_written += write_indexes (self, output + n_written, output_length - n_written); | |
53 | } |