grub2/grub-efi: fix CVEs

Porting patches from grub2_2.06-3~deb11u1 to fix below CVEs:
CVE-2021-3695
CVE-2021-3696
CVE-2021-3697
CVE-2022-28733
CVE-2022-28734

The source code of grub2_2.06-3~deb11u1 is from:
https://snapshot.debian.org/archive/debian/20220807T030023Z/pool
/main/g/grub2/grub2_2.06-3~deb11u1.debian.tar.xz

The relationship between commits and CVEs is as below:
(1)CVE-2021-3695
commit <video/readers/png: Drop greyscale support to fix heap
out-of-bounds write>
(2)CVE-2021-3696
commit <video/readers/png: Avoid heap OOB R/W inserting huff table items>
(3)CVE-2021-3697
commit <video/readers/jpeg: Block int underflow -> wild pointer write>
(4)CVE-2022-28733
commit <net/ip: Do IP fragment maths safely>
(5)CVE-2022-28734
commit <net/http: Fix OOB write for split http headers>
commit <net/http: Error out on headers with LF without CR>

Test plan:
 - PASS: build grub2/grub-efi.
 - PASS: build-image and install and boot up on lab/qemu.
 - PASS: check that the "stx.N" version number is right for both
         bios(grub2 ver) and uefi(grub-efi ver) boot.

Partial-Bug: #2034119

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Change-Id: Ia27b1ee225f13e9c4ad08a0828f93ea37f8d3dfb
This commit is contained in:
Li Zhou 2023-09-05 13:54:52 +08:00
parent 7b62e540d7
commit 44f318a38d
14 changed files with 884 additions and 0 deletions

View File

@ -0,0 +1,171 @@
From 157486f818ecbe26b7962f5795a8f48393ba5169 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 18:51:35 +1000
Subject: [PATCH 1/6] video/readers/png: Drop greyscale support to fix heap
out-of-bounds write
A 16-bit greyscale PNG without alpha is processed in the following loop:
for (i = 0; i < (data->image_width * data->image_height);
i++, d1 += 4, d2 += 2)
{
d1[R3] = d2[1];
d1[G3] = d2[1];
d1[B3] = d2[1];
}
The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
but there are only 3 bytes allocated for storage. This means that image
data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
out of every 4 following the end of the image.
This has existed since greyscale support was added in 2013 in commit
3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
and attempting to load it causes grub-emu to crash - I don't think this code
has ever worked.
Delete all PNG greyscale support.
Fixes: CVE-2021-3695
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 87 +++--------------------------------
1 file changed, 7 insertions(+), 80 deletions(-)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 4827b9c..1e35eae 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -100,7 +100,7 @@ struct grub_png_data
unsigned image_width, image_height;
int bpp, is_16bit;
- int raw_bytes, is_gray, is_alpha, is_palette;
+ int raw_bytes, is_alpha, is_palette;
int row_bytes, color_bits;
grub_uint8_t *image_data;
@@ -284,13 +284,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->bpp = 3;
else
{
- data->is_gray = 1;
- data->bpp = 1;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: color type not supported");
}
if ((color_bits != 8) && (color_bits != 16)
&& (color_bits != 4
- || !(data->is_gray || data->is_palette)))
+ || !data->is_palette))
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"png: bit depth must be 8 or 16");
@@ -319,7 +319,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
}
#ifndef GRUB_CPU_WORDS_BIGENDIAN
- if (data->is_16bit || data->is_gray || data->is_palette)
+ if (data->is_16bit || data->is_palette)
#endif
{
data->image_data = grub_calloc (data->image_height, data->row_bytes);
@@ -863,27 +863,8 @@ grub_png_convert_image (struct grub_png_data *data)
int shift;
int mask = (1 << data->color_bits) - 1;
unsigned j;
- if (data->is_gray)
- {
- /* Generic formula is
- (0xff * i) / ((1U << data->color_bits) - 1)
- but for allowed bit depth of 1, 2 and for it's
- equivalent to
- (0xff / ((1U << data->color_bits) - 1)) * i
- Precompute the multipliers to avoid division.
- */
-
- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
- for (i = 0; i < (1U << data->color_bits); i++)
- {
- grub_uint8_t col = multipliers[data->color_bits] * i;
- palette[i][0] = col;
- palette[i][1] = col;
- palette[i][2] = col;
- }
- }
- else
- grub_memcpy (palette, data->palette, 3 << data->color_bits);
+
+ grub_memcpy (palette, data->palette, 3 << data->color_bits);
d1c = d1;
d2c = d2;
for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
@@ -920,60 +901,6 @@ grub_png_convert_image (struct grub_png_data *data)
}
return;
}
-
- if (data->is_gray)
- {
- switch (data->bpp)
- {
- case 4:
- /* 16-bit gray with alpha. */
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 4)
- {
- d1[R4] = d2[3];
- d1[G4] = d2[3];
- d1[B4] = d2[3];
- d1[A4] = d2[1];
- }
- break;
- case 2:
- if (data->is_16bit)
- /* 16-bit gray without alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R3] = d2[1];
- d1[G3] = d2[1];
- d1[B3] = d2[1];
- }
- }
- else
- /* 8-bit gray with alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R4] = d2[1];
- d1[G4] = d2[1];
- d1[B4] = d2[1];
- d1[A4] = d2[0];
- }
- }
- break;
- /* 8-bit gray without alpha. */
- case 1:
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 3, d2++)
- {
- d1[R3] = d2[0];
- d1[G3] = d2[0];
- d1[B3] = d2[0];
- }
- break;
- }
- return;
- }
{
/* Only copy the upper 8 bit. */
--
2.17.1

View File

@ -0,0 +1,42 @@
From b54f7505732ad5c6237a133c0a1cf00774f13508 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 23:25:07 +1000
Subject: [PATCH 2/6] video/readers/png: Avoid heap OOB R/W inserting huff
table items
In fuzzing we observed crashes where a code would attempt to be inserted
into a huffman table before the start, leading to a set of heap OOB reads
and writes as table entries with negative indices were shifted around and
the new code written in.
Catch the case where we would underflow the array and bail.
Fixes: CVE-2021-3696
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 1e35eae..0356f91 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -420,6 +420,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
for (i = len; i < ht->max_length; i++)
n += ht->maxval[i];
+ if (n > ht->num_values)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: out of range inserting huffman table item");
+ return;
+ }
+
for (i = 0; i < n; i++)
ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
--
2.17.1

View File

@ -0,0 +1,79 @@
From a10c2350a766f9b315735931a49499a7e2c77bf3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 4 Sep 2023 16:32:43 +0800
Subject: [PATCH 3/6] video/readers/jpeg: Block int underflow -> wild pointer
write
Certain 1 px wide images caused a wild pointer write in
grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
we have the following loop:
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
We did not check if vb * width >= hb * nc1.
On a 64-bit platform, if that turns out to be negative, it will underflow,
be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
we see data->bitmap_ptr jump, e.g.:
0x6180_0000_0480 to
0x6181_0000_0498
^
~--- carry has occurred and this pointer is now far away from
any object.
On a 32-bit platform, it will decrement the pointer, creating a pointer
that won't crash but will overwrite random data.
Catch the underflow and error out.
Fixes: CVE-2021-3697
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
[lz: Adapt the patch for context changes]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/video/readers/jpeg.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 0eeea0e..fdaef18 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -23,6 +23,7 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/bufio.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -643,6 +644,7 @@ static grub_err_t
grub_jpeg_decode_data (struct grub_jpeg_data *data)
{
unsigned c1, vb, hb, nr1, nc1;
+ unsigned stride_a, stride_b, stride;
int rst = data->dri;
vb = 8 << data->log_vs;
@@ -654,8 +656,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
return grub_error(GRUB_ERR_BAD_FILE_TYPE,
"jpeg: attempted to decode data before start of stream");
+ if (grub_mul(vb, data->image_width, &stride_a) ||
+ grub_mul(hb, nc1, &stride_b) ||
+ grub_sub(stride_a, stride_b, &stride))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: cannot decode image with these dimensions");
+
for (; data->r1 < nr1 && (!data->dri || rst);
- data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+ data->r1++, data->bitmap_ptr += stride * 3)
for (c1 = 0; c1 < nc1 && (!data->dri || rst);
c1++, rst--, data->bitmap_ptr += hb * 3)
{
--
2.17.1

View File

@ -0,0 +1,46 @@
From 5d2f1e350e39677938a70c17a163f1a9cde36a18 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 20 Dec 2021 19:41:21 +1100
Subject: [PATCH 4/6] net/ip: Do IP fragment maths safely
This avoids an underflow and subsequent unpleasantness.
Fixes: CVE-2022-28733
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/ip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index ea5edf8..74e4e8b 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -25,6 +25,7 @@
#include <grub/net/netbuff.h>
#include <grub/mm.h>
#include <grub/priority_queue.h>
+#include <grub/safemath.h>
#include <grub/time.h>
struct iphdr {
@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
{
rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
+ (nb->tail - nb->data));
- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
+
+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
+ &rsm->total_len))
+ {
+ grub_dprintf ("net", "IP reassembly size underflow\n");
+ return GRUB_ERR_NONE;
+ }
+
rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
if (!rsm->asm_netbuff)
{
--
2.17.1

View File

@ -0,0 +1,48 @@
From f37943427c5bf16a0003d3049221da698006f6f3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 18:17:03 +1100
Subject: [PATCH 5/6] net/http: Fix OOB write for split http headers
GRUB has special code for handling an http header that is split
across two packets.
The code tracks the end of line by looking for a "\n" byte. The
code for split headers has always advanced the pointer just past the
end of the line, whereas the code that handles unsplit headers does
not advance the pointer. This extra advance causes the length to be
one greater, which breaks an assumption in parse_line(), leading to
it writing a NUL byte one byte past the end of the buffer where we
reconstruct the line from the two packets.
It's conceivable that an attacker controlled set of packets could
cause this to zero out the first byte of the "next" pointer of the
grub_mm_region structure following the current_line buffer.
Do not advance the pointer in the split header case.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index b616cf4..a19b0a2 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -190,9 +190,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
int have_line = 1;
char *t;
ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
- if (ptr)
- ptr++;
- else
+ if (ptr == NULL)
{
have_line = 0;
ptr = (char *) nb->tail;
--
2.17.1

View File

@ -0,0 +1,50 @@
From c96929e9eea455b07e0c2e06bc401eea6bf2be11 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 19:04:40 +1100
Subject: [PATCH 6/6] net/http: Error out on headers with LF without CR
In a similar vein to the previous patch, parse_line() would write
a NUL byte past the end of the buffer if there was an HTTP header
with a LF rather than a CRLF.
RFC-2616 says:
Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value (as defined in section 3.6).
We don't support quoted sections or continuation lines, etc.
If we see an LF that's not part of a CRLF, bail out.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index a19b0a2..1fa62b5 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
char *end = ptr + len;
while (end > ptr && *(end - 1) == '\r')
end--;
+
+ /* LF without CR. */
+ if (end == ptr + len)
+ {
+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
+ return GRUB_ERR_NONE;
+ }
*end = 0;
+
/* Trailing CRLF. */
if (data->in_chunk_len == 1)
{
--
2.17.1

View File

@ -32,3 +32,9 @@
0032-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch
0033-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
0034-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
0035-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
0036-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
0037-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
0038-net-ip-Do-IP-fragment-maths-safely.patch
0039-net-http-Fix-OOB-write-for-split-http-headers.patch
0040-net-http-Error-out-on-headers-with-LF-without-CR.patch

View File

@ -0,0 +1,171 @@
From 157486f818ecbe26b7962f5795a8f48393ba5169 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 18:51:35 +1000
Subject: [PATCH 1/6] video/readers/png: Drop greyscale support to fix heap
out-of-bounds write
A 16-bit greyscale PNG without alpha is processed in the following loop:
for (i = 0; i < (data->image_width * data->image_height);
i++, d1 += 4, d2 += 2)
{
d1[R3] = d2[1];
d1[G3] = d2[1];
d1[B3] = d2[1];
}
The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
but there are only 3 bytes allocated for storage. This means that image
data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
out of every 4 following the end of the image.
This has existed since greyscale support was added in 2013 in commit
3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
and attempting to load it causes grub-emu to crash - I don't think this code
has ever worked.
Delete all PNG greyscale support.
Fixes: CVE-2021-3695
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 87 +++--------------------------------
1 file changed, 7 insertions(+), 80 deletions(-)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 4827b9c..1e35eae 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -100,7 +100,7 @@ struct grub_png_data
unsigned image_width, image_height;
int bpp, is_16bit;
- int raw_bytes, is_gray, is_alpha, is_palette;
+ int raw_bytes, is_alpha, is_palette;
int row_bytes, color_bits;
grub_uint8_t *image_data;
@@ -284,13 +284,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->bpp = 3;
else
{
- data->is_gray = 1;
- data->bpp = 1;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: color type not supported");
}
if ((color_bits != 8) && (color_bits != 16)
&& (color_bits != 4
- || !(data->is_gray || data->is_palette)))
+ || !data->is_palette))
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"png: bit depth must be 8 or 16");
@@ -319,7 +319,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
}
#ifndef GRUB_CPU_WORDS_BIGENDIAN
- if (data->is_16bit || data->is_gray || data->is_palette)
+ if (data->is_16bit || data->is_palette)
#endif
{
data->image_data = grub_calloc (data->image_height, data->row_bytes);
@@ -863,27 +863,8 @@ grub_png_convert_image (struct grub_png_data *data)
int shift;
int mask = (1 << data->color_bits) - 1;
unsigned j;
- if (data->is_gray)
- {
- /* Generic formula is
- (0xff * i) / ((1U << data->color_bits) - 1)
- but for allowed bit depth of 1, 2 and for it's
- equivalent to
- (0xff / ((1U << data->color_bits) - 1)) * i
- Precompute the multipliers to avoid division.
- */
-
- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
- for (i = 0; i < (1U << data->color_bits); i++)
- {
- grub_uint8_t col = multipliers[data->color_bits] * i;
- palette[i][0] = col;
- palette[i][1] = col;
- palette[i][2] = col;
- }
- }
- else
- grub_memcpy (palette, data->palette, 3 << data->color_bits);
+
+ grub_memcpy (palette, data->palette, 3 << data->color_bits);
d1c = d1;
d2c = d2;
for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
@@ -920,60 +901,6 @@ grub_png_convert_image (struct grub_png_data *data)
}
return;
}
-
- if (data->is_gray)
- {
- switch (data->bpp)
- {
- case 4:
- /* 16-bit gray with alpha. */
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 4)
- {
- d1[R4] = d2[3];
- d1[G4] = d2[3];
- d1[B4] = d2[3];
- d1[A4] = d2[1];
- }
- break;
- case 2:
- if (data->is_16bit)
- /* 16-bit gray without alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R3] = d2[1];
- d1[G3] = d2[1];
- d1[B3] = d2[1];
- }
- }
- else
- /* 8-bit gray with alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R4] = d2[1];
- d1[G4] = d2[1];
- d1[B4] = d2[1];
- d1[A4] = d2[0];
- }
- }
- break;
- /* 8-bit gray without alpha. */
- case 1:
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 3, d2++)
- {
- d1[R3] = d2[0];
- d1[G3] = d2[0];
- d1[B3] = d2[0];
- }
- break;
- }
- return;
- }
{
/* Only copy the upper 8 bit. */
--
2.17.1

View File

@ -0,0 +1,42 @@
From b54f7505732ad5c6237a133c0a1cf00774f13508 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 23:25:07 +1000
Subject: [PATCH 2/6] video/readers/png: Avoid heap OOB R/W inserting huff
table items
In fuzzing we observed crashes where a code would attempt to be inserted
into a huffman table before the start, leading to a set of heap OOB reads
and writes as table entries with negative indices were shifted around and
the new code written in.
Catch the case where we would underflow the array and bail.
Fixes: CVE-2021-3696
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 1e35eae..0356f91 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -420,6 +420,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
for (i = len; i < ht->max_length; i++)
n += ht->maxval[i];
+ if (n > ht->num_values)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: out of range inserting huffman table item");
+ return;
+ }
+
for (i = 0; i < n; i++)
ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
--
2.17.1

View File

@ -0,0 +1,79 @@
From a10c2350a766f9b315735931a49499a7e2c77bf3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 4 Sep 2023 16:32:43 +0800
Subject: [PATCH 3/6] video/readers/jpeg: Block int underflow -> wild pointer
write
Certain 1 px wide images caused a wild pointer write in
grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
we have the following loop:
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
We did not check if vb * width >= hb * nc1.
On a 64-bit platform, if that turns out to be negative, it will underflow,
be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
we see data->bitmap_ptr jump, e.g.:
0x6180_0000_0480 to
0x6181_0000_0498
^
~--- carry has occurred and this pointer is now far away from
any object.
On a 32-bit platform, it will decrement the pointer, creating a pointer
that won't crash but will overwrite random data.
Catch the underflow and error out.
Fixes: CVE-2021-3697
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
[lz: Adapt the patch for context changes]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/video/readers/jpeg.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 0eeea0e..fdaef18 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -23,6 +23,7 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/bufio.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -643,6 +644,7 @@ static grub_err_t
grub_jpeg_decode_data (struct grub_jpeg_data *data)
{
unsigned c1, vb, hb, nr1, nc1;
+ unsigned stride_a, stride_b, stride;
int rst = data->dri;
vb = 8 << data->log_vs;
@@ -654,8 +656,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
return grub_error(GRUB_ERR_BAD_FILE_TYPE,
"jpeg: attempted to decode data before start of stream");
+ if (grub_mul(vb, data->image_width, &stride_a) ||
+ grub_mul(hb, nc1, &stride_b) ||
+ grub_sub(stride_a, stride_b, &stride))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: cannot decode image with these dimensions");
+
for (; data->r1 < nr1 && (!data->dri || rst);
- data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+ data->r1++, data->bitmap_ptr += stride * 3)
for (c1 = 0; c1 < nc1 && (!data->dri || rst);
c1++, rst--, data->bitmap_ptr += hb * 3)
{
--
2.17.1

View File

@ -0,0 +1,46 @@
From 5d2f1e350e39677938a70c17a163f1a9cde36a18 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 20 Dec 2021 19:41:21 +1100
Subject: [PATCH 4/6] net/ip: Do IP fragment maths safely
This avoids an underflow and subsequent unpleasantness.
Fixes: CVE-2022-28733
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/ip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index ea5edf8..74e4e8b 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -25,6 +25,7 @@
#include <grub/net/netbuff.h>
#include <grub/mm.h>
#include <grub/priority_queue.h>
+#include <grub/safemath.h>
#include <grub/time.h>
struct iphdr {
@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
{
rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
+ (nb->tail - nb->data));
- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
+
+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
+ &rsm->total_len))
+ {
+ grub_dprintf ("net", "IP reassembly size underflow\n");
+ return GRUB_ERR_NONE;
+ }
+
rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
if (!rsm->asm_netbuff)
{
--
2.17.1

View File

@ -0,0 +1,48 @@
From f37943427c5bf16a0003d3049221da698006f6f3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 18:17:03 +1100
Subject: [PATCH 5/6] net/http: Fix OOB write for split http headers
GRUB has special code for handling an http header that is split
across two packets.
The code tracks the end of line by looking for a "\n" byte. The
code for split headers has always advanced the pointer just past the
end of the line, whereas the code that handles unsplit headers does
not advance the pointer. This extra advance causes the length to be
one greater, which breaks an assumption in parse_line(), leading to
it writing a NUL byte one byte past the end of the buffer where we
reconstruct the line from the two packets.
It's conceivable that an attacker controlled set of packets could
cause this to zero out the first byte of the "next" pointer of the
grub_mm_region structure following the current_line buffer.
Do not advance the pointer in the split header case.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index b616cf4..a19b0a2 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -190,9 +190,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
int have_line = 1;
char *t;
ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
- if (ptr)
- ptr++;
- else
+ if (ptr == NULL)
{
have_line = 0;
ptr = (char *) nb->tail;
--
2.17.1

View File

@ -0,0 +1,50 @@
From c96929e9eea455b07e0c2e06bc401eea6bf2be11 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 19:04:40 +1100
Subject: [PATCH 6/6] net/http: Error out on headers with LF without CR
In a similar vein to the previous patch, parse_line() would write
a NUL byte past the end of the buffer if there was an HTTP header
with a LF rather than a CRLF.
RFC-2616 says:
Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value (as defined in section 3.6).
We don't support quoted sections or continuation lines, etc.
If we see an LF that's not part of a CRLF, bail out.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index a19b0a2..1fa62b5 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
char *end = ptr + len;
while (end > ptr && *(end - 1) == '\r')
end--;
+
+ /* LF without CR. */
+ if (end == ptr + len)
+ {
+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
+ return GRUB_ERR_NONE;
+ }
*end = 0;
+
/* Trailing CRLF. */
if (data->in_chunk_len == 1)
{
--
2.17.1

View File

@ -15,3 +15,9 @@
0015-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch
0016-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
0017-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
0018-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
0019-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
0020-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
0021-net-ip-Do-IP-fragment-maths-safely.patch
0022-net-http-Fix-OOB-write-for-split-http-headers.patch
0023-net-http-Error-out-on-headers-with-LF-without-CR.patch