1From 34b85a6e07014383ddcad09f99ff239ad752dd1a Mon Sep 17 00:00:00 2001
2From: Daniel Axtens <dja@axtens.net>
3Date: Fri, 15 Jan 2021 13:29:53 +1100
4Subject: [PATCH] video/readers/jpeg: Catch OOB reads/writes in
5 grub_jpeg_decode_du()
6
7The key line is:
8
9  du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
10
11jpeg_zigzag_order is grub_uint8_t[64].
12
13I don't understand JPEG decoders quite well enough to explain what's
14going on here. However, I observe sometimes pos=64, which leads to an
15OOB read of the jpeg_zigzag_order global then an OOB write to du.
16That leads to various unpleasant memory corruption conditions.
17
18Catch where pos >= ARRAY_SIZE(jpeg_zigzag_order) and bail.
19
20Signed-off-by: Daniel Axtens <dja@axtens.net>
21Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
22Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
23---
24 grub-core/video/readers/jpeg.c | 8 ++++++++
25 1 file changed, 8 insertions(+)
26
27diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
28index 23f919a..e514812 100644
29--- a/grub-core/video/readers/jpeg.c
30+++ b/grub-core/video/readers/jpeg.c
31@@ -526,6 +526,14 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
32       val = grub_jpeg_get_number (data, num & 0xF);
33       num >>= 4;
34       pos += num;
35+
36+      if (pos >= ARRAY_SIZE (jpeg_zigzag_order))
37+	{
38+	  grub_error (GRUB_ERR_BAD_FILE_TYPE,
39+		      "jpeg: invalid position in zigzag order!?");
40+	  return;
41+	}
42+
43       du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
44       pos++;
45     }
46--
472.14.2
48
49