aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpsykose <alice@ayaya.dev>2023-05-24 01:11:39 +0000
committerpsykose <alice@ayaya.dev>2023-05-24 03:12:09 +0200
commit65a32726eb51a5f50ecb909d49945cce80d4669d (patch)
treea978cd8e855580d83186b2818562146f42edaea4
parentb93dde5a847466bab4d0a2c43776ea1325d37840 (diff)
main/grub: patch CVE-2021-3697
-rw-r--r--main/grub/APKBUILD12
-rw-r--r--main/grub/CVE-2021-3697-1.patch259
-rw-r--r--main/grub/CVE-2021-3697-2.patch33
-rw-r--r--main/grub/CVE-2021-3697-3.patch48
-rw-r--r--main/grub/CVE-2021-3697-4.patch78
5 files changed, 429 insertions, 1 deletions
diff --git a/main/grub/APKBUILD b/main/grub/APKBUILD
index 0512789d375..adf136df94b 100644
--- a/main/grub/APKBUILD
+++ b/main/grub/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Timo Teräs <timo.teras@iki.fi>
pkgname=grub
pkgver=2.06
-pkgrel=11
+pkgrel=12
pkgdesc="Bootloader with support for Linux, Multiboot and more"
url="https://www.gnu.org/software/grub/"
arch="all !s390x"
@@ -67,9 +67,15 @@ source="https://ftp.gnu.org/gnu/grub/grub-$pkgver.tar.xz
0022-templates-fix-lang-locale-detection.patch
0023-build-force-no-pie.patch
fix-riscv64.patch
+ CVE-2021-3697-1.patch
+ CVE-2021-3697-2.patch
+ CVE-2021-3697-3.patch
+ CVE-2021-3697-4.patch
"
# secfixes:
+# 2.06-r12:
+# - CVE-2021-3697
# 2.06-r0:
# - CVE-2021-3418
# - CVE-2020-10713
@@ -305,4 +311,8 @@ b69a24bf6d19fc262108d6064555754c8662ba1b8e4f68717419acafc18c5e04117c01bd40da3a72
d4e311ed2a849d9424eb215b55e217e7c0db80b54c7dc67679eb1ec81892e4dff77d4e837abbd17117c2ae6378a6bd06b0d57d2b4856d4045feafe1be43c2067 0022-templates-fix-lang-locale-detection.patch
552a0034b4f721d56b3ad7eb23b47b278690c219ba1a12fbf1f82eb88b03132c0b73fe11934f7ab26e7e2c819f1c20f06422ae2df26dbeaec8f0eaa3dfd4f03d 0023-build-force-no-pie.patch
e2a968890fb54f5a070e1de0a30ae6f0a71952ce5f607bfc43798852398142e342e1477b2b51d74f06ad83f49c35f3c81f6c8c9f9d012bc4a327c266a520124f fix-riscv64.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
"
diff --git a/main/grub/CVE-2021-3697-1.patch b/main/grub/CVE-2021-3697-1.patch
new file mode 100644
index 00000000000..420b455eed3
--- /dev/null
+++ b/main/grub/CVE-2021-3697-1.patch
@@ -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
+
diff --git a/main/grub/CVE-2021-3697-2.patch b/main/grub/CVE-2021-3697-2.patch
new file mode 100644
index 00000000000..c090349a655
--- /dev/null
+++ b/main/grub/CVE-2021-3697-2.patch
@@ -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
+
diff --git a/main/grub/CVE-2021-3697-3.patch b/main/grub/CVE-2021-3697-3.patch
new file mode 100644
index 00000000000..98e234701a7
--- /dev/null
+++ b/main/grub/CVE-2021-3697-3.patch
@@ -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
+
diff --git a/main/grub/CVE-2021-3697-4.patch b/main/grub/CVE-2021-3697-4.patch
new file mode 100644
index 00000000000..8554faac4ef
--- /dev/null
+++ b/main/grub/CVE-2021-3697-4.patch
@@ -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
+