grub2: update to SBAT 4
This commit is contained in:
Родитель
24bae75d0d
Коммит
8b259d90fa
|
@ -12,7 +12,7 @@
|
|||
Summary: Signed GRand Unified Bootloader for %{buildarch} systems
|
||||
Name: grub2-efi-binary-signed-%{buildarch}
|
||||
Version: 2.06
|
||||
Release: 12%{?dist}
|
||||
Release: 13%{?dist}
|
||||
License: GPLv3+
|
||||
Vendor: Microsoft Corporation
|
||||
Distribution: Mariner
|
||||
|
@ -77,6 +77,9 @@ cp %{SOURCE3} %{buildroot}/boot/efi/EFI/BOOT/%{grubpxeefiname}
|
|||
/boot/efi/EFI/BOOT/%{grubpxeefiname}
|
||||
|
||||
%changelog
|
||||
* Thu Feb 15 2024 Dan Streetman <ddstreet@microsoft.com> - 2.06-13
|
||||
- match grub2 version
|
||||
|
||||
* Wed Oct 18 2023 Gary Swalling <gaswal@microsoft.com> - 2.06-12
|
||||
- Bump release number to match grub release number
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
"gnulib-d271f868a8df9bbec29049d01e056481b7a1a263.tar.gz": "4e23415ae2977ffca15e07419ceff3e9334d0369eafc9e7ae2578f8dd9a4839c",
|
||||
"grub-2.06.tar.gz": "660eaa2355a4045d8d0cdb5765169d1cad9912ec07873b86c9c6d55dbaa9dfca",
|
||||
"macros.grub2": "b03f6f713601214406971de53538dfc25136bf836f09a663eaffc4332a72c38b",
|
||||
"sbat.csv.in": "11106562bccc09244f573be85ba2fe07cd1c830ef5bf3cc5e83a194c717880a5"
|
||||
"sbat.csv.in": "e024eeb72dea5016d3494931d236e1b17f7db34f8d07676c942b6af0fda6fb8d"
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
Summary: GRand Unified Bootloader
|
||||
Name: grub2
|
||||
Version: 2.06
|
||||
Release: 12%{?dist}
|
||||
Release: 13%{?dist}
|
||||
License: GPLv3+
|
||||
Vendor: Microsoft Corporation
|
||||
Distribution: Mariner
|
||||
|
@ -85,6 +85,24 @@ Patch0199: 0199-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
|
|||
Patch0200: 0200-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
|
||||
Patch0201: 0201-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch
|
||||
Patch0202: 0202-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch
|
||||
# Required to reach SBAT 3
|
||||
Patch: sbat-3-0001-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch
|
||||
Patch: sbat-3-0004-font-Remove-grub_font_dup_glyph.patch
|
||||
Patch: sbat-3-0005-font-Fix-integer-overflow-in-ensure_comb_space.patch
|
||||
Patch: sbat-3-0006-font-Fix-integer-overflow-in-BMP-index.patch
|
||||
Patch: sbat-3-0007-font-Fix-integer-underflow-in-binary-search-of-char-.patch
|
||||
Patch: sbat-3-0008-kern-efi-sb-Enforce-verification-of-font-files.patch
|
||||
Patch: sbat-3-0009-fbutil-Fix-integer-overflow.patch
|
||||
Patch: sbat-3-0011-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch
|
||||
Patch: sbat-3-0012-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
|
||||
Patch: sbat-3-0013-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
|
||||
# Required to reach SBAT 4
|
||||
Patch: sbat-4-0001-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
|
||||
Patch: sbat-4-0002-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
|
||||
Patch: sbat-4-0003-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch
|
||||
Patch: sbat-4-0004-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch
|
||||
Patch: sbat-4-0005-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch
|
||||
Patch: sbat-4-0006-fs-ntfs-Make-code-more-readable.patch
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: device-mapper-devel
|
||||
BuildRequires: python3
|
||||
|
@ -387,6 +405,9 @@ cp $GRUB_PXE_MODULE_SOURCE $EFI_BOOT_DIR/$GRUB_PXE_MODULE_NAME
|
|||
%{_sysconfdir}/default/grub.d
|
||||
|
||||
%changelog
|
||||
* Thu Feb 15 2024 Dan Streetman <ddstreet@microsoft.com> - 2.06-13
|
||||
- update grub to sbat 4
|
||||
|
||||
* Wed Oct 18 2023 Gary Swalling <gaswal@microsoft.com> - 2.06-12
|
||||
- CVE-2021-3695 CVE-2021-3696 CVE-2021-3697 CVE-2022-28733 CVE-2022-28734
|
||||
CVE-2022-28735 CVE-2022-28736 and increment SBAT level to 2
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
From f6b6236077f059e64ee315f2d7acb8fa4eda87c5 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Wed, 3 Aug 2022 19:45:33 +0800
|
||||
Subject: [PATCH 01/13] font: Reject glyphs exceeds font->max_glyph_width or
|
||||
font->max_glyph_height
|
||||
|
||||
Check glyph's width and height against limits specified in font's
|
||||
metadata. Reject the glyph (and font) if such limits are exceeded.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index 42189c325..756ca0abf 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
||||
|| read_be_uint16 (font->file, &height) != 0
|
||||
|| read_be_int16 (font->file, &xoff) != 0
|
||||
|| read_be_int16 (font->file, &yoff) != 0
|
||||
- || read_be_int16 (font->file, &dwidth) != 0)
|
||||
+ || read_be_int16 (font->file, &dwidth) != 0
|
||||
+ || width > font->max_char_width
|
||||
+ || height > font->max_char_height)
|
||||
{
|
||||
remove_font (font);
|
||||
return 0;
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From c51292274ded3259eb04c2f1c8d253ffbdb5216a Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 5 Aug 2022 02:13:29 +0800
|
||||
Subject: [PATCH 04/13] font: Remove grub_font_dup_glyph()
|
||||
|
||||
Remove grub_font_dup_glyph() since nobody is using it since 2013, and
|
||||
I'm too lazy to fix the integer overflow problem in it.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 14 --------------
|
||||
1 file changed, 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index e6548892f..a8576ffec 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
|
||||
return best_glyph;
|
||||
}
|
||||
|
||||
-#if 0
|
||||
-static struct grub_font_glyph *
|
||||
-grub_font_dup_glyph (struct grub_font_glyph *glyph)
|
||||
-{
|
||||
- static struct grub_font_glyph *ret;
|
||||
- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
|
||||
- if (!ret)
|
||||
- return NULL;
|
||||
- grub_memcpy (ret, glyph, sizeof (*ret)
|
||||
- + (glyph->width * glyph->height + 7) / 8);
|
||||
- return ret;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
/* FIXME: suboptimal. */
|
||||
static void
|
||||
grub_font_blit_glyph (struct grub_font_glyph *target,
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
From 23843fe8947e4da955a05ad3d1858725bfcb56c8 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 5 Aug 2022 02:27:05 +0800
|
||||
Subject: [PATCH 05/13] font: Fix integer overflow in ensure_comb_space()
|
||||
|
||||
In fact it can't overflow at all because glyph_id->ncomb is only 8-bit
|
||||
wide. But let's keep safe if somebody changes the width of glyph_id->ncomb
|
||||
in the future. This patch also fixes the inconsistency between
|
||||
render_max_comb_glyphs and render_combining_glyphs when grub_malloc()
|
||||
returns NULL.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index a8576ffec..9e3e0a94e 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
|
||||
if (glyph_id->ncomb <= render_max_comb_glyphs)
|
||||
return;
|
||||
|
||||
- render_max_comb_glyphs = 2 * glyph_id->ncomb;
|
||||
- if (render_max_comb_glyphs < 8)
|
||||
+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs))
|
||||
+ render_max_comb_glyphs = 0;
|
||||
+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8)
|
||||
render_max_comb_glyphs = 8;
|
||||
grub_free (render_combining_glyphs);
|
||||
- render_combining_glyphs = grub_malloc (render_max_comb_glyphs
|
||||
- * sizeof (render_combining_glyphs[0]));
|
||||
+ render_combining_glyphs = (render_max_comb_glyphs > 0) ?
|
||||
+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL;
|
||||
if (!render_combining_glyphs)
|
||||
- grub_errno = 0;
|
||||
+ {
|
||||
+ render_max_comb_glyphs = 0;
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
}
|
||||
|
||||
int
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
From b9396daf1c2e3cdc0a1e69b056852e0769fb24de Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Mon, 15 Aug 2022 02:04:58 +0800
|
||||
Subject: [PATCH 06/13] font: Fix integer overflow in BMP index
|
||||
|
||||
The BMP index (font->bmp_idx) is designed as a reverse lookup table of
|
||||
char entries (font->char_index), in order to speed up lookups for BMP
|
||||
chars (i.e. code < 0x10000). The values in BMP index are the subscripts
|
||||
of the corresponding char entries, stored in grub_uint16_t, while 0xffff
|
||||
means not found.
|
||||
|
||||
This patch fixes the problem of large subscript truncated to grub_uint16_t,
|
||||
leading BMP index to return wrong char entry or report false miss. The
|
||||
code now checks for bounds and uses BMP index as a hint, and fallbacks
|
||||
to binary-search if necessary.
|
||||
|
||||
On the occasion add a comment about BMP index is initialized to 0xffff.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 13 +++++++++----
|
||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index 9e3e0a94e..e4cb0d867 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
||||
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
||||
if (!font->bmp_idx)
|
||||
return 1;
|
||||
+
|
||||
+ /* Init the BMP index array to 0xffff. */
|
||||
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
|
||||
|
||||
|
||||
@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (entry->code < 0x10000)
|
||||
+ if (entry->code < 0x10000 && i < 0xffff)
|
||||
font->bmp_idx[entry->code] = i;
|
||||
|
||||
last_code = entry->code;
|
||||
@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
|
||||
/* Use BMP index if possible. */
|
||||
if (code < 0x10000 && font->bmp_idx)
|
||||
{
|
||||
- if (font->bmp_idx[code] == 0xffff)
|
||||
- return 0;
|
||||
- return &table[font->bmp_idx[code]];
|
||||
+ if (font->bmp_idx[code] < 0xffff)
|
||||
+ return &table[font->bmp_idx[code]];
|
||||
+ /*
|
||||
+ * When we are here then lookup in BMP index result in miss,
|
||||
+ * fallthough to binary-search.
|
||||
+ */
|
||||
}
|
||||
|
||||
/* Do a binary search in `char_index', which is ordered by code point. */
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
From 1d2015598cc7a9fca4b39186273e3519a88e80c7 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Sun, 14 Aug 2022 18:09:38 +0800
|
||||
Subject: [PATCH 07/13] font: Fix integer underflow in binary search of char
|
||||
index
|
||||
|
||||
If search target is less than all entries in font->index then "hi"
|
||||
variable is set to -1, which translates to SIZE_MAX and leads to errors.
|
||||
|
||||
This patch fixes the problem by replacing the entire binary search code
|
||||
with the libstdc++'s std::lower_bound() implementation.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 40 ++++++++++++++++++++++------------------
|
||||
1 file changed, 22 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index e4cb0d867..abd412a5e 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
|
||||
static inline struct char_index_entry *
|
||||
find_glyph (const grub_font_t font, grub_uint32_t code)
|
||||
{
|
||||
- struct char_index_entry *table;
|
||||
- grub_size_t lo;
|
||||
- grub_size_t hi;
|
||||
- grub_size_t mid;
|
||||
+ struct char_index_entry *table, *first, *end;
|
||||
+ grub_size_t len;
|
||||
|
||||
table = font->char_index;
|
||||
+ if (table == NULL)
|
||||
+ return NULL;
|
||||
|
||||
/* Use BMP index if possible. */
|
||||
if (code < 0x10000 && font->bmp_idx)
|
||||
@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
|
||||
*/
|
||||
}
|
||||
|
||||
- /* Do a binary search in `char_index', which is ordered by code point. */
|
||||
- lo = 0;
|
||||
- hi = font->num_chars - 1;
|
||||
-
|
||||
- if (!table)
|
||||
- return 0;
|
||||
+ /*
|
||||
+ * Do a binary search in char_index which is ordered by code point.
|
||||
+ * The code below is the same as libstdc++'s std::lower_bound().
|
||||
+ */
|
||||
+ first = table;
|
||||
+ len = font->num_chars;
|
||||
+ end = first + len;
|
||||
|
||||
- while (lo <= hi)
|
||||
+ while (len > 0)
|
||||
{
|
||||
- mid = lo + (hi - lo) / 2;
|
||||
- if (code < table[mid].code)
|
||||
- hi = mid - 1;
|
||||
- else if (code > table[mid].code)
|
||||
- lo = mid + 1;
|
||||
+ grub_size_t half = len >> 1;
|
||||
+ struct char_index_entry *middle = first + half;
|
||||
+
|
||||
+ if (middle->code < code)
|
||||
+ {
|
||||
+ first = middle + 1;
|
||||
+ len = len - half - 1;
|
||||
+ }
|
||||
else
|
||||
- return &table[mid];
|
||||
+ len = half;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return (first < end && first->code == code) ? first : NULL;
|
||||
}
|
||||
|
||||
/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 93a786a00163e50c29f0394df198518617e1c9a5 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Sun, 14 Aug 2022 15:51:54 +0800
|
||||
Subject: [PATCH 08/13] kern/efi/sb: Enforce verification of font files
|
||||
|
||||
As a mitigation and hardening measure enforce verification of font
|
||||
files. Then only trusted font files can be load. This will reduce the
|
||||
attack surface at cost of losing the ability of end-users to customize
|
||||
fonts if e.g. UEFI Secure Boot is enabled. Vendors can always customize
|
||||
fonts because they have ability to pack fonts into their GRUB bundles.
|
||||
|
||||
This goal is achieved by:
|
||||
|
||||
* Removing GRUB_FILE_TYPE_FONT from shim lock verifier's
|
||||
skip-verification list.
|
||||
|
||||
* Adding GRUB_FILE_TYPE_FONT to lockdown verifier's defer-auth list,
|
||||
so font files must be verified by a verifier before they can be loaded.
|
||||
|
||||
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/sb.c | 1 -
|
||||
grub-core/kern/lockdown.c | 1 +
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index 89c4bb3fd..db42c2539 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -145,7 +145,6 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
|
||||
case GRUB_FILE_TYPE_TESTLOAD:
|
||||
case GRUB_FILE_TYPE_GET_SIZE:
|
||||
- case GRUB_FILE_TYPE_FONT:
|
||||
case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
|
||||
case GRUB_FILE_TYPE_CAT:
|
||||
case GRUB_FILE_TYPE_HEXCAT:
|
||||
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
|
||||
index 0bc70fd42..af6d493cd 100644
|
||||
--- a/grub-core/kern/lockdown.c
|
||||
+++ b/grub-core/kern/lockdown.c
|
||||
@@ -51,6 +51,7 @@ lockdown_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
|
||||
case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
+ case GRUB_FILE_TYPE_FONT:
|
||||
*flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
|
||||
|
||||
/* Fall through. */
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
From 1eac01c147b4d85d2ec4a7e5671fa4345f2e8549 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Tue, 6 Sep 2022 03:03:21 +0800
|
||||
Subject: [PATCH 09/13] fbutil: Fix integer overflow
|
||||
|
||||
Expressions like u64 = u32 * u32 are unsafe because their products are
|
||||
truncated to u32 even if left hand side is u64. This patch fixes all
|
||||
problems like that one in fbutil.
|
||||
|
||||
To get right result not only left hand side have to be u64 but it's also
|
||||
necessary to cast at least one of the operands of all leaf operators of
|
||||
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
|
||||
u64 = (u64)u32 * u32 + (u64)u32 * u32.
|
||||
|
||||
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
|
||||
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
|
||||
not overflow grub_uint64_t.
|
||||
|
||||
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
|
||||
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
|
||||
|
||||
This patch also adds a comment to grub_video_fb_get_video_ptr() which
|
||||
says it's arguments must be valid and no sanity check is performed
|
||||
(like its siblings in grub-core/video/fb/fbutil.c).
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/video/fb/fbutil.c | 4 ++--
|
||||
include/grub/fbutil.h | 13 +++++++++----
|
||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
|
||||
index b98bb51fe..25ef39f47 100644
|
||||
--- a/grub-core/video/fb/fbutil.c
|
||||
+++ b/grub-core/video/fb/fbutil.c
|
||||
@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source,
|
||||
case 1:
|
||||
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
|
||||
{
|
||||
- int bit_index = y * source->mode_info->width + x;
|
||||
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
|
||||
grub_uint8_t *ptr = source->data + bit_index / 8;
|
||||
int bit_pos = 7 - bit_index % 8;
|
||||
color = (*ptr >> bit_pos) & 0x01;
|
||||
@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source,
|
||||
case 1:
|
||||
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
|
||||
{
|
||||
- int bit_index = y * source->mode_info->width + x;
|
||||
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
|
||||
grub_uint8_t *ptr = source->data + bit_index / 8;
|
||||
int bit_pos = 7 - bit_index % 8;
|
||||
*ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
|
||||
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
|
||||
index 4205eb917..78a1ab3b4 100644
|
||||
--- a/include/grub/fbutil.h
|
||||
+++ b/include/grub/fbutil.h
|
||||
@@ -31,14 +31,19 @@ struct grub_video_fbblit_info
|
||||
grub_uint8_t *data;
|
||||
};
|
||||
|
||||
-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
|
||||
- and it doesn't make sense, in general, to ask for a pointer
|
||||
- to a particular pixel's data. */
|
||||
+/*
|
||||
+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
|
||||
+ * and it doesn't make sense, in general, to ask for a pointer
|
||||
+ * to a particular pixel's data.
|
||||
+ *
|
||||
+ * This function assumes that bounds checking has been done in previous phase
|
||||
+ * and they are opted out in here.
|
||||
+ */
|
||||
static inline void *
|
||||
grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel;
|
||||
+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel;
|
||||
}
|
||||
|
||||
/* Advance pointer by VAL bytes. If there is no unaligned access available,
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
From 9d81f71c6b8f55cf20cd56f5fe29c759df9b48cc Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Mon, 24 Oct 2022 07:15:41 +0800
|
||||
Subject: [PATCH 11/13] font: Harden grub_font_blit_glyph() and
|
||||
grub_font_blit_glyph_mirror()
|
||||
|
||||
As a mitigation and hardening measure add sanity checks to
|
||||
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
|
||||
makes these two functions do nothing if target blitting area isn't fully
|
||||
contained in target bitmap. Therefore, if complex calculations in caller
|
||||
overflows and malicious coordinates are given, we are still safe because
|
||||
any coordinates which result in out-of-bound-write are rejected. However,
|
||||
this patch only checks for invalid coordinates, and doesn't provide any
|
||||
protection against invalid source glyph or destination glyph, e.g.
|
||||
mismatch between glyph size and buffer size.
|
||||
|
||||
This hardening measure is designed to mitigate possible overflows in
|
||||
blit_comb(). If overflow occurs, it may return invalid bounding box
|
||||
during dry run and call grub_font_blit_glyph() with malicious
|
||||
coordinates during actual blitting. However, we are still safe because
|
||||
the scratch glyph itself is valid, although its size makes no sense, and
|
||||
any invalid coordinates are rejected.
|
||||
|
||||
It would be better to call grub_fatal() if illegal parameter is detected.
|
||||
However, doing this may end up in a dangerous recursion because grub_fatal()
|
||||
would print messages to the screen and we are in the progress of drawing
|
||||
characters on the screen.
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index 3d3d803e8..cf15dc2f9 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -1069,8 +1069,15 @@ static void
|
||||
grub_font_blit_glyph (struct grub_font_glyph *target,
|
||||
struct grub_font_glyph *src, unsigned dx, unsigned dy)
|
||||
{
|
||||
+ grub_uint16_t max_x, max_y;
|
||||
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
|
||||
unsigned i, j;
|
||||
+
|
||||
+ /* Harden against out-of-bound writes. */
|
||||
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
|
||||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
|
||||
+ return;
|
||||
+
|
||||
for (i = 0; i < src->height; i++)
|
||||
{
|
||||
src_bit = (src->width * i) % 8;
|
||||
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
|
||||
struct grub_font_glyph *src,
|
||||
unsigned dx, unsigned dy)
|
||||
{
|
||||
+ grub_uint16_t max_x, max_y;
|
||||
unsigned tgt_bit, src_byte, tgt_byte;
|
||||
signed src_bit;
|
||||
unsigned i, j;
|
||||
+
|
||||
+ /* Harden against out-of-bound writes. */
|
||||
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
|
||||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
|
||||
+ return;
|
||||
+
|
||||
for (i = 0; i < src->height; i++)
|
||||
{
|
||||
src_bit = (src->width * i + src->width - 1) % 8;
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From 22b77b87e10a3a6c9bb9885415bc9a9c678378e6 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 28 Oct 2022 17:29:16 +0800
|
||||
Subject: [PATCH 12/13] font: Assign null_font to glyphs in ascii_font_glyph[]
|
||||
|
||||
The calculations in blit_comb() need information from glyph's font, e.g.
|
||||
grub_font_get_xheight(main_glyph->font). However, main_glyph->font is
|
||||
NULL if main_glyph comes from ascii_font_glyph[]. Therefore
|
||||
grub_font_get_*() crashes because of NULL pointer.
|
||||
|
||||
There is already a solution, the null_font. So, assign it to those glyphs
|
||||
in ascii_font_glyph[].
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/font/font.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index cf15dc2f9..3821937e6 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code)
|
||||
ascii_font_glyph[current]->offset_x = 0;
|
||||
ascii_font_glyph[current]->offset_y = -2;
|
||||
ascii_font_glyph[current]->device_width = 8;
|
||||
- ascii_font_glyph[current]->font = NULL;
|
||||
+ ascii_font_glyph[current]->font = &null_font;
|
||||
|
||||
grub_memcpy (ascii_font_glyph[current]->bitmap,
|
||||
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From 1514678888595ef41a968a0c69b7ff769edd1e9c Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 28 Oct 2022 21:31:39 +0800
|
||||
Subject: [PATCH 13/13] normal/charset: Fix an integer overflow in
|
||||
grub_unicode_aglomerate_comb()
|
||||
|
||||
The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255.
|
||||
However, code in grub_unicode_aglomerate_comb() doesn't check for an
|
||||
overflow when incrementing out->ncomb. If out->ncomb is already 255,
|
||||
after incrementing it will get 0 instead of 256, and cause illegal
|
||||
memory access in subsequent processing.
|
||||
|
||||
This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max
|
||||
acceptable value of ncomb. The code now checks for this limit and
|
||||
ignores additional combining characters when limit is reached.
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/normal/charset.c | 3 +++
|
||||
include/grub/unicode.h | 2 ++
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
|
||||
index 000e687bd..4f6647116 100644
|
||||
--- a/grub-core/normal/charset.c
|
||||
+++ b/grub-core/normal/charset.c
|
||||
@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||
if (!haveout)
|
||||
continue;
|
||||
|
||||
+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX)
|
||||
+ continue;
|
||||
+
|
||||
if (comb_type == GRUB_UNICODE_COMB_MC
|
||||
|| comb_type == GRUB_UNICODE_COMB_ME
|
||||
|| comb_type == GRUB_UNICODE_COMB_MN)
|
||||
diff --git a/include/grub/unicode.h b/include/grub/unicode.h
|
||||
index 71a4d1a54..9360b0b97 100644
|
||||
--- a/include/grub/unicode.h
|
||||
+++ b/include/grub/unicode.h
|
||||
@@ -147,7 +147,9 @@ struct grub_unicode_glyph
|
||||
grub_uint8_t bidi_level:6; /* minimum: 6 */
|
||||
enum grub_bidi_type bidi_type:5; /* minimum: :5 */
|
||||
|
||||
+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1)
|
||||
unsigned ncomb:8;
|
||||
+
|
||||
/* Hint by unicode subsystem how wide this character usually is.
|
||||
Real width is determined by font. Set only in UTF-8 stream. */
|
||||
int estimated_width:8;
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
From 43651027d24e62a7a463254165e1e46e42aecdea Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:31:57 +0300
|
||||
Subject: [PATCH 1/6] fs/ntfs: Fix an OOB write when parsing the
|
||||
$ATTRIBUTE_LIST attribute for the $MFT file
|
||||
|
||||
When parsing an extremely fragmented $MFT file, i.e., the file described
|
||||
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
|
||||
containing bytes read from the underlying drive to store sector numbers,
|
||||
which are consumed later to read data from these sectors into another buffer.
|
||||
|
||||
These sectors numbers, two 32-bit integers, are always stored at predefined
|
||||
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
|
||||
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
|
||||
|
||||
However, when parsing a specially-crafted file system image, this may cause
|
||||
the NTFS code to write these integers beyond the buffer boundary, likely
|
||||
causing the GRUB memory allocator to misbehave or fail. These integers contain
|
||||
values which are controlled by on-disk structures of the NTFS file system.
|
||||
|
||||
Such modification and resulting misbehavior may touch a memory range not
|
||||
assigned to the GRUB and owned by firmware or another EFI application/driver.
|
||||
|
||||
This fix introduces checks to ensure that these sector numbers are never
|
||||
written beyond the boundary.
|
||||
|
||||
Fixes: CVE-2023-4692
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index bbdbe24ad..c3c4db117 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
}
|
||||
if (at->attr_end)
|
||||
{
|
||||
- grub_uint8_t *pa;
|
||||
+ grub_uint8_t *pa, *pa_end;
|
||||
|
||||
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||
if (at->emft_buf == NULL)
|
||||
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
}
|
||||
at->attr_nxt = at->edat_buf;
|
||||
at->attr_end = at->edat_buf + u32at (pa, 0x30);
|
||||
+ pa_end = at->edat_buf + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
||||
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||
}
|
||||
at->flags |= GRUB_NTFS_AF_ALST;
|
||||
while (at->attr_nxt < at->attr_end)
|
||||
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
at->flags |= GRUB_NTFS_AF_GPOS;
|
||||
at->attr_cur = at->attr_nxt;
|
||||
pa = at->attr_cur;
|
||||
+
|
||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
grub_set_unaligned32 ((char *) pa + 0x10,
|
||||
grub_cpu_to_le32 (at->mft->data->mft_start));
|
||||
grub_set_unaligned32 ((char *) pa + 0x14,
|
||||
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
{
|
||||
if (*pa != attr)
|
||||
break;
|
||||
+
|
||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (read_attr
|
||||
(at, pa + 0x10,
|
||||
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From 0ed2458cc4eff6d9a9199527e2a0b6d445802f94 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:32:33 +0300
|
||||
Subject: [PATCH 2/6] fs/ntfs: Fix an OOB read when reading data from the
|
||||
resident $DATA attribute
|
||||
|
||||
When reading a file containing resident data, i.e., the file data is stored in
|
||||
the $DATA attribute within the NTFS file record, not in external clusters,
|
||||
there are no checks that this resident data actually fits the corresponding
|
||||
file record segment.
|
||||
|
||||
When parsing a specially-crafted file system image, the current NTFS code will
|
||||
read the file data from an arbitrary, attacker-chosen memory offset and of
|
||||
arbitrary, attacker-chosen length.
|
||||
|
||||
This allows an attacker to display arbitrary chunks of memory, which could
|
||||
contain sensitive information like password hashes or even plain-text,
|
||||
obfuscated passwords from BS EFI variables.
|
||||
|
||||
This fix implements a check to ensure that resident data is read from the
|
||||
corresponding file record segment only.
|
||||
|
||||
Fixes: CVE-2023-4693
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index c3c4db117..a68e173d8 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
|
||||
{
|
||||
if (ofs + len > u32at (pa, 0x10))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
|
||||
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
|
||||
+
|
||||
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
|
||||
+
|
||||
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
+
|
||||
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
|
||||
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
+
|
||||
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
From 7e5f031a6a6a3decc2360a7b0c71abbe598e7354 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:33:17 +0300
|
||||
Subject: [PATCH 3/6] fs/ntfs: Fix an OOB read when parsing directory entries
|
||||
from resident and non-resident index attributes
|
||||
|
||||
This fix introduces checks to ensure that index entries are never read
|
||||
beyond the corresponding directory index.
|
||||
|
||||
The lack of this check is a minor issue, likely not exploitable in any way.
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index a68e173d8..2d78b96e1 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -599,7 +599,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
|
||||
}
|
||||
|
||||
static int
|
||||
-list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos,
|
||||
grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
|
||||
{
|
||||
grub_uint8_t *np;
|
||||
@@ -610,6 +610,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
grub_uint8_t namespace;
|
||||
char *ustr;
|
||||
|
||||
+ if ((pos >= end_pos) || (end_pos - pos < 0x52))
|
||||
+ break;
|
||||
+
|
||||
if (pos[0xC] & 2) /* end signature */
|
||||
break;
|
||||
|
||||
@@ -617,6 +620,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
ns = *(np++);
|
||||
namespace = *(np++);
|
||||
|
||||
+ if (2 * ns > end_pos - pos - 0x52)
|
||||
+ break;
|
||||
+
|
||||
/*
|
||||
* Ignore files in DOS namespace, as they will reappear as Win32
|
||||
* names.
|
||||
@@ -806,7 +812,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
cur_pos += 0x10; /* Skip index root */
|
||||
- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data);
|
||||
+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0),
|
||||
+ at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||
+ hook, hook_data);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
@@ -893,6 +901,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
(const grub_uint8_t *) "INDX")))
|
||||
goto done;
|
||||
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)],
|
||||
+ indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
|
||||
hook, hook_data);
|
||||
if (ret)
|
||||
goto done;
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From 7a5a116739fa6d8a625da7d6b9272c9a2462f967 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:33:44 +0300
|
||||
Subject: [PATCH 4/6] fs/ntfs: Fix an OOB read when parsing bitmaps for index
|
||||
attributes
|
||||
|
||||
This fix introduces checks to ensure that bitmaps for directory indices
|
||||
are never read beyond their actual sizes.
|
||||
|
||||
The lack of this check is a minor issue, likely not exploitable in any way.
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index 2d78b96e1..bb70c89fb 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -843,6 +843,25 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
|
||||
if (is_resident)
|
||||
{
|
||||
+ if (bitmap_len > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap too large");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (cur_pos >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
|
||||
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
|
||||
bitmap_len);
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From 1fe82c41e070385e273d7bb1cfb482627a3c28e8 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:38:19 +0300
|
||||
Subject: [PATCH 5/6] fs/ntfs: Fix an OOB read when parsing a volume label
|
||||
|
||||
This fix introduces checks to ensure that an NTFS volume label is always
|
||||
read from the corresponding file record segment.
|
||||
|
||||
The current NTFS code allows the volume label string to be read from an
|
||||
arbitrary, attacker-chosen memory location. However, the bytes read are
|
||||
always treated as UTF-16LE. So, the final string displayed is mostly
|
||||
unreadable and it can't be easily converted back to raw bytes.
|
||||
|
||||
The lack of this check is a minor issue, likely not causing a significant
|
||||
data leak.
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index bb70c89fb..ff5e3740f 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -1213,13 +1213,29 @@ grub_ntfs_label (grub_device_t device, char **label)
|
||||
|
||||
init_attr (&mft->attr, mft);
|
||||
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
|
||||
+
|
||||
+ if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa < 0x16)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
||||
{
|
||||
int len;
|
||||
|
||||
len = u32at (pa, 0x10) / 2;
|
||||
pa += u16at (pa, 0x14);
|
||||
- *label = get_utf8 (pa, len);
|
||||
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
|
||||
+ *label = get_utf8 (pa, len);
|
||||
+ else
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
||||
}
|
||||
|
||||
fail:
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
From e58b870ff926415e23fc386af41ff81b2f588763 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:40:07 +0300
|
||||
Subject: [PATCH 6/6] fs/ntfs: Make code more readable
|
||||
|
||||
Move some calls used to access NTFS attribute header fields into
|
||||
functions with human-readable names.
|
||||
|
||||
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 48 +++++++++++++++++++++++++++++++--------------
|
||||
1 file changed, 33 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index ff5e3740f..de435aa14 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -52,6 +52,24 @@ u64at (void *ptr, grub_size_t ofs)
|
||||
return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs));
|
||||
}
|
||||
|
||||
+static grub_uint16_t
|
||||
+first_attr_off (void *mft_buf_ptr)
|
||||
+{
|
||||
+ return u16at (mft_buf_ptr, 0x14);
|
||||
+}
|
||||
+
|
||||
+static grub_uint16_t
|
||||
+res_attr_data_off (void *res_attr_ptr)
|
||||
+{
|
||||
+ return u16at (res_attr_ptr, 0x14);
|
||||
+}
|
||||
+
|
||||
+static grub_uint32_t
|
||||
+res_attr_data_len (void *res_attr_ptr)
|
||||
+{
|
||||
+ return u32at (res_attr_ptr, 0x10);
|
||||
+}
|
||||
+
|
||||
grub_ntfscomp_func_t grub_ntfscomp_func;
|
||||
|
||||
static grub_err_t
|
||||
@@ -106,7 +124,7 @@ init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
|
||||
{
|
||||
at->mft = mft;
|
||||
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
|
||||
- at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
|
||||
+ at->attr_nxt = mft->buf + first_attr_off (mft->buf);
|
||||
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
|
||||
}
|
||||
|
||||
@@ -154,7 +172,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
|
||||
+ new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
|
||||
while (*new_pos != 0xFF)
|
||||
{
|
||||
if ((*new_pos == *at->attr_cur)
|
||||
@@ -213,7 +231,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
}
|
||||
else
|
||||
{
|
||||
- at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
||||
+ at->attr_nxt = at->attr_end + res_attr_data_off (pa);
|
||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
||||
pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||
}
|
||||
@@ -399,20 +417,20 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
|
||||
|
||||
if (pa[8] == 0)
|
||||
{
|
||||
- if (ofs + len > u32at (pa, 0x10))
|
||||
+ if (ofs + len > res_attr_data_len (pa))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
|
||||
|
||||
- if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ if (res_attr_data_len (pa) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
|
||||
|
||||
if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
|
||||
- if (u16at (pa, 0x14) + u32at (pa, 0x10) >
|
||||
+ if (res_attr_data_off (pa) + res_attr_data_len (pa) >
|
||||
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
|
||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
|
||||
- grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
|
||||
+ grub_memcpy (dest, pa + res_attr_data_off (pa) + ofs, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -556,7 +574,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
|
||||
(unsigned long long) mftno);
|
||||
|
||||
if (!pa[8])
|
||||
- mft->size = u32at (pa, 0x10);
|
||||
+ mft->size = res_attr_data_len (pa);
|
||||
else
|
||||
mft->size = u64at (pa, 0x30);
|
||||
|
||||
@@ -805,7 +823,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
(u32at (cur_pos, 0x18) != 0x490024) ||
|
||||
(u32at (cur_pos, 0x1C) != 0x300033))
|
||||
continue;
|
||||
- cur_pos += u16at (cur_pos, 0x14);
|
||||
+ cur_pos += res_attr_data_off (cur_pos);
|
||||
if (*cur_pos != 0x30) /* Not filename index */
|
||||
continue;
|
||||
break;
|
||||
@@ -834,7 +852,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
int is_resident = (cur_pos[8] == 0);
|
||||
|
||||
- bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
|
||||
+ bitmap_len = ((is_resident) ? res_attr_data_len (cur_pos) :
|
||||
u32at (cur_pos, 0x28));
|
||||
|
||||
bmp = grub_malloc (bitmap_len);
|
||||
@@ -855,14 +873,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
|
||||
+ if (res_attr_data_off (cur_pos) + res_attr_data_len (cur_pos) >
|
||||
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
||||
goto done;
|
||||
}
|
||||
|
||||
- grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
|
||||
+ grub_memcpy (bmp, cur_pos + res_attr_data_off (cur_pos),
|
||||
bitmap_len);
|
||||
}
|
||||
else
|
||||
@@ -1226,12 +1244,12 @@ grub_ntfs_label (grub_device_t device, char **label)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
||||
+ if ((pa) && (pa[8] == 0) && (res_attr_data_len (pa)))
|
||||
{
|
||||
int len;
|
||||
|
||||
- len = u32at (pa, 0x10) / 2;
|
||||
- pa += u16at (pa, 0x14);
|
||||
+ len = res_attr_data_len (pa) / 2;
|
||||
+ pa += res_attr_data_off (pa);
|
||||
if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
|
||||
*label = get_utf8 (pa, len);
|
||||
else
|
||||
--
|
||||
2.34.1
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
grub,2,Free Software Foundation,grub,@@VERSION@@,https://www.gnu.org/software/grub/
|
||||
grub.mariner,2,Microsoft,grub2,@@VERSION_RELEASE@@,https://github.com/microsoft/CBL-Mariner
|
||||
grub,4,Free Software Foundation,grub,@@VERSION@@,https://www.gnu.org/software/grub/
|
||||
grub.mariner,3,Microsoft,grub2,@@VERSION_RELEASE@@,https://github.com/microsoft/CBL-Mariner
|
||||
|
|
Загрузка…
Ссылка в новой задаче