main/grub: patch CVE-2022-46908

This commit is contained in:
Kevin Daudt 2023-12-05 12:47:22 +00:00
parent 6dcefbc63b
commit ab2e398b1f
5 changed files with 431 additions and 1 deletions

View File

@ -2,7 +2,7 @@
# Maintainer: Timo Teräs <timo.teras@iki.fi>
pkgname=grub
pkgver=2.06
pkgrel=2
pkgrel=3
pkgdesc="Bootloader with support for Linux, Multiboot and more"
url="https://www.gnu.org/software/grub/"
arch="all !s390x"
@ -22,6 +22,10 @@ subpackages="
$pkgname-bash-completion:bashcomp:noarch
"
# secfixes:
# 2.06-r3:
# - CVE-2021-3697
# currently grub only builds on x86*, aarch64 and ppc* systems
case "$CARCH" in
x86) flavors="efi bios";;
@ -51,6 +55,10 @@ source="https://ftp.gnu.org/gnu/grub/grub-$pkgver.tar.xz
0007-RISC-V-Use-common-linux-loader.patch
0008-fix-build-error-in-binutils-2.36.patch
0009-fix-kernel-version-detection.patch
CVE-2021-3697-1.patch
CVE-2021-3697-2.patch
CVE-2021-3697-3.patch
CVE-2021-3697-4.patch
"
prepare() {
@ -256,4 +264,8 @@ aa2fbabeab2e8f517128f0d81d3c76eba18b24518b616d4574ffaaec7d4765e02b5b118caf04da1e
721c9d7aefd9d9fdd4fe92c229122c3311e75266a9419a12f5f77536099070a232b6c4ff3c33ab5a2cb6f7f917ae0d6510b09045d2f035f87c65b4dd7f09d3ee 0007-RISC-V-Use-common-linux-loader.patch
8c35663ef72683bd23c18e75134a0ddb1bb9a7c053ed87691e2ac5c9765fdf802761a6ad54f8bdc7999679d9cc5ebea9c01f1c0f615ac90505f7a398129d157b 0008-fix-build-error-in-binutils-2.36.patch
d4432a36286f0ad7d3527d34e20daf9fbef24d6037171582ae3ccdd51668ffe422b87d984f107a9b4dcf019b89ac76dd322d64e42bbfa64bb6789d3d897fc1f2 0009-fix-kernel-version-detection.patch
1ef0c87ab121a71453f9f34725ee33d21dfcc0918662a7483afc8213d773c7b663c6950c2120d54184ac833e8cb51312b1edc42d7649ec37529069d31c692a72 CVE-2021-3697-1.patch
0fd9e41fabd96ef119b9c24d7f380ad62060d7e3ebb58b832341adb4c682d2b10b2b5e36edc670460fe61e9355460b3af5a32a6c9d91f7fc9c9a2d53f52a15da CVE-2021-3697-2.patch
bf9a07f739d2fabd133cdfd360d96f7960b940421130597dadf596bacf0489c64d229b5079ef7bc930e9d6a5c4ad823906340a1d608c4b37571235b976485829 CVE-2021-3697-3.patch
9c249a2e1067c25aa3b6a7c9daaf9fa1634c67ccc9a5b98b312fe8b3638ceb2531887cda9bd5c0a2e3c8846033ae9b2821a90a552ffe69335aee952e8eeaefdf CVE-2021-3697-4.patch
"

View File

@ -0,0 +1,259 @@
Patch-Source: https://salsa.debian.org/grub-team/grub/-/commit/40be99c5f8162887d1922fb9428b39de4cdad3af
--
From 40be99c5f8162887d1922fb9428b39de4cdad3af Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 28 Jun 2021 14:16:14 +1000
Subject: [PATCH] video/readers/jpeg: Abort sooner if a read operation fails
Fuzzing revealed some inputs that were taking a long time, potentially
forever, because they did not bail quickly upon encountering an I/O error.
Try to catch I/O errors sooner and bail out.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 86 +++++++++++++++++++++++++++-------
1 file changed, 70 insertions(+), 16 deletions(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index e31602f76..10225abd5 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -109,9 +109,17 @@ static grub_uint8_t
grub_jpeg_get_byte (struct grub_jpeg_data *data)
{
grub_uint8_t r;
+ grub_ssize_t bytes_read;
r = 0;
- grub_file_read (data->file, &r, 1);
+ bytes_read = grub_file_read (data->file, &r, 1);
+
+ if (bytes_read != 1)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: unexpected end of data");
+ return 0;
+ }
return r;
}
@@ -120,9 +128,17 @@ static grub_uint16_t
grub_jpeg_get_word (struct grub_jpeg_data *data)
{
grub_uint16_t r;
+ grub_ssize_t bytes_read;
r = 0;
- grub_file_read (data->file, &r, sizeof (grub_uint16_t));
+ bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t));
+
+ if (bytes_read != sizeof (grub_uint16_t))
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: unexpected end of data");
+ return 0;
+ }
return grub_be_to_cpu16 (r);
}
@@ -135,6 +151,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
if (data->bit_mask == 0)
{
data->bit_save = grub_jpeg_get_byte (data);
+ if (grub_errno != GRUB_ERR_NONE) {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: file read error");
+ return 0;
+ }
if (data->bit_save == JPEG_ESC_CHAR)
{
if (grub_jpeg_get_byte (data) != 0)
@@ -143,6 +164,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data)
"jpeg: invalid 0xFF in data stream");
return 0;
}
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error");
+ return 0;
+ }
}
data->bit_mask = 0x80;
}
@@ -161,7 +187,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
return 0;
msb = value = grub_jpeg_get_bit (data);
- for (i = 1; i < num; i++)
+ for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++)
value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
if (!msb)
value += 1 - (1 << num);
@@ -202,6 +228,8 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
while (data->file->offset + sizeof (count) + 1 <= next_marker)
{
id = grub_jpeg_get_byte (data);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
ac = (id >> 4) & 1;
id &= 0xF;
if (id > 1)
@@ -252,6 +280,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
next_marker = data->file->offset;
next_marker += grub_jpeg_get_word (data);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
if (next_marker > data->file->size)
{
@@ -263,6 +293,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
<= next_marker)
{
id = grub_jpeg_get_byte (data);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
if (id >= 0x10) /* Upper 4-bit is precision. */
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"jpeg: only 8-bit precision is supported");
@@ -294,6 +326,9 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
next_marker = data->file->offset;
next_marker += grub_jpeg_get_word (data);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
if (grub_jpeg_get_byte (data) != 8)
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"jpeg: only 8-bit precision is supported");
@@ -319,6 +354,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
ss = grub_jpeg_get_byte (data); /* Sampling factor. */
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
if (!id)
{
grub_uint8_t vs, hs;
@@ -498,7 +535,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du)
}
}
-static void
+static grub_err_t
grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
{
int h1, h2, qt;
@@ -513,6 +550,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
data->dc_value[id] +=
grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
pos = 1;
while (pos < ARRAY_SIZE (data->quan_table[qt]))
@@ -527,11 +567,13 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
num >>= 4;
pos += num;
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
if (pos >= ARRAY_SIZE (jpeg_zigzag_order))
{
- grub_error (GRUB_ERR_BAD_FILE_TYPE,
- "jpeg: invalid position in zigzag order!?");
- return;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: invalid position in zigzag order!?");
}
du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
@@ -539,6 +581,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
}
grub_jpeg_idct_transform (du);
+ return GRUB_ERR_NONE;
}
static void
@@ -597,7 +640,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
data_offset += grub_jpeg_get_word (data);
cc = grub_jpeg_get_byte (data);
-
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
if (cc != 3 && cc != 1)
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"jpeg: component count must be 1 or 3");
@@ -610,7 +654,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
id = grub_jpeg_get_byte (data) - 1;
if ((id < 0) || (id >= 3))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
-
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
ht = grub_jpeg_get_byte (data);
data->comp_index[id][1] = (ht >> 4);
data->comp_index[id][2] = (ht & 0xF) + 2;
@@ -618,11 +663,14 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) ||
(data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index");
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
}
grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */
grub_jpeg_get_word (data);
-
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
if (data->file->offset != data_offset)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
@@ -640,6 +688,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
{
unsigned c1, vb, hb, nr1, nc1;
int rst = data->dri;
+ grub_err_t err = GRUB_ERR_NONE;
vb = 8 << data->log_vs;
hb = 8 << data->log_hs;
@@ -660,17 +709,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
for (r2 = 0; r2 < (1U << data->log_vs); r2++)
for (c2 = 0; c2 < (1U << data->log_hs); c2++)
- grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
+ {
+ err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
+ if (err != GRUB_ERR_NONE)
+ return err;
+ }
if (data->color_components >= 3)
{
- grub_jpeg_decode_du (data, 1, data->cbdu);
- grub_jpeg_decode_du (data, 2, data->crdu);
+ err = grub_jpeg_decode_du (data, 1, data->cbdu);
+ if (err != GRUB_ERR_NONE)
+ return err;
+ err = grub_jpeg_decode_du (data, 2, data->crdu);
+ if (err != GRUB_ERR_NONE)
+ return err;
}
- if (grub_errno)
- return grub_errno;
-
nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb;
nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
--
GitLab

View File

@ -0,0 +1,33 @@
Patch-Source: https://salsa.debian.org/grub-team/grub/-/commit/610c5986058312cfc0375fc04f88fcc116bdd043
--
From 610c5986058312cfc0375fc04f88fcc116bdd043 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 28 Jun 2021 14:16:58 +1000
Subject: [PATCH] video/readers/jpeg: Do not reallocate a given huff table
Fix a memory leak where an invalid file could cause us to reallocate
memory for a huffman table we had already allocated memory for.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 10225abd5..caa211f06 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -245,6 +245,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
n += count[i];
id += ac * 2;
+ if (data->huff_value[id] != NULL)
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: attempt to reallocate huffman table");
data->huff_value[id] = grub_malloc (n);
if (grub_errno)
return grub_errno;
--
GitLab

View File

@ -0,0 +1,48 @@
Patch-Source: https://salsa.debian.org/grub-team/grub/-/commit/9286f0009b922571c247012e699c3ed5f6e918bc
--
From 9286f0009b922571c247012e699c3ed5f6e918bc Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 28 Jun 2021 14:25:17 +1000
Subject: [PATCH] video/readers/jpeg: Refuse to handle multiple start of
streams
An invalid file could contain multiple start of stream blocks, which
would cause us to reallocate and leak our bitmap. Refuse to handle
multiple start of streams.
Additionally, fix a grub_error() call formatting.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index caa211f06..1df1171d7 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -677,6 +677,9 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
if (data->file->offset != data_offset)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
+ if (*data->bitmap)
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks");
+
if (grub_video_bitmap_create (data->bitmap, data->image_width,
data->image_height,
GRUB_VIDEO_BLIT_FORMAT_RGB_888))
@@ -699,8 +702,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs);
if (data->bitmap_ptr == NULL)
- return grub_error(GRUB_ERR_BAD_FILE_TYPE,
- "jpeg: attempted to decode data before start of stream");
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: attempted to decode data before start of stream");
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
--
GitLab

View File

@ -0,0 +1,78 @@
Patch-Source: https://salsa.debian.org/grub-team/grub/-/commit/a10c2350a766f9b315735931a49499a7e2c77bf3
--
From a10c2350a766f9b315735931a49499a7e2c77bf3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 7 Jul 2021 15:38:19 +1000
Subject: [PATCH] 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>
---
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 1df1171d7..97a533b24 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+");
@@ -693,6 +694,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;
grub_err_t err = GRUB_ERR_NONE;
@@ -705,8 +707,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)
{
--
GitLab