From daea2d82190d43509133a100774ab5118e3e4dae Mon Sep 17 00:00:00 2001
From: Li Zhou
Date: Sat, 7 Oct 2023 19:41:38 -0700
Subject: [PATCH] grub2/grub-efi: fix CVE-2023-4692/CVE-2023-4693
Porting patches from grub2_2.06-3~deb11u6 to fix
CVE-2023-4692/CVE-2023-4693.
The source code of grub2_2.06-3~deb11u6 is from:
https://snapshot.debian.org/archive/debian-security/20231006T185629Z/
pool/updates/main/g/grub2/grub2_2.06-3~deb11u6.debian.tar.xz
Patch for CVE-2023-4692:
Patch for CVE-2023-4693:
No content changes for all the patches from debian release.
We do this because grub2/grub-efi is ported from wrlinux for
secure boot bringing up.
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.
Closes-bug: 2038742
Signed-off-by: Li Zhou
Change-Id: I7c8e11952fb409be93e9d777bf7da7b87414a95d
---
...OB-write-when-parsing-the-ATTRIBUTE_.patch | 89 +++++++++++++++++++
...OB-read-when-reading-data-from-the-r.patch | 54 +++++++++++
grub/grub-efi/debian/patches/series | 2 +
...OB-write-when-parsing-the-ATTRIBUTE_.patch | 89 +++++++++++++++++++
...OB-read-when-reading-data-from-the-r.patch | 54 +++++++++++
grub/grub2/debian/patches/series | 2 +
6 files changed, 290 insertions(+)
create mode 100644 grub/grub-efi/debian/patches/0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
create mode 100644 grub/grub-efi/debian/patches/0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
create mode 100644 grub/grub2/debian/patches/0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
create mode 100644 grub/grub2/debian/patches/0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
diff --git a/grub/grub-efi/debian/patches/0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch b/grub/grub-efi/debian/patches/0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
new file mode 100644
index 000000000..06279b8d2
--- /dev/null
+++ b/grub/grub-efi/debian/patches/0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
@@ -0,0 +1,89 @@
+From: Maxim Suhanov
+Date: Mon, 28 Aug 2023 16:31:57 +0300
+Subject: 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
+Signed-off-by: Maxim Suhanov
+Reviewed-by: Daniel Kiper
+---
+ 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 bbdbe24..c3c4db1 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),
diff --git a/grub/grub-efi/debian/patches/0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch b/grub/grub-efi/debian/patches/0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
new file mode 100644
index 000000000..d762c064c
--- /dev/null
+++ b/grub/grub-efi/debian/patches/0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
@@ -0,0 +1,54 @@
+From: Maxim Suhanov
+Date: Mon, 28 Aug 2023 16:32:33 +0300
+Subject: 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
+Signed-off-by: Maxim Suhanov
+Reviewed-by: Daniel Kiper
+---
+ 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 c3c4db1..a68e173 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;
+ }
+
diff --git a/grub/grub-efi/debian/patches/series b/grub/grub-efi/debian/patches/series
index a08485380..d5b07b4c5 100644
--- a/grub/grub-efi/debian/patches/series
+++ b/grub/grub-efi/debian/patches/series
@@ -24,6 +24,8 @@
0041-loader-efi-chainloader-Simplify-the-loader-state.patch
0042-commands-boot-Add-API-to-pass-context-to-loader.patch
0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch
+0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
+0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
lat/0003-Make-UEFI-watchdog-behaviour-configurable.patch
lat/0004-correct-grub_errno.patch
lat/0005-grub-verify-Add-skip_check_cfg-variable.patch
diff --git a/grub/grub2/debian/patches/0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch b/grub/grub2/debian/patches/0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
new file mode 100644
index 000000000..06279b8d2
--- /dev/null
+++ b/grub/grub2/debian/patches/0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
@@ -0,0 +1,89 @@
+From: Maxim Suhanov
+Date: Mon, 28 Aug 2023 16:31:57 +0300
+Subject: 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
+Signed-off-by: Maxim Suhanov
+Reviewed-by: Daniel Kiper
+---
+ 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 bbdbe24..c3c4db1 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),
diff --git a/grub/grub2/debian/patches/0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch b/grub/grub2/debian/patches/0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
new file mode 100644
index 000000000..d762c064c
--- /dev/null
+++ b/grub/grub2/debian/patches/0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
@@ -0,0 +1,54 @@
+From: Maxim Suhanov
+Date: Mon, 28 Aug 2023 16:32:33 +0300
+Subject: 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
+Signed-off-by: Maxim Suhanov
+Reviewed-by: Daniel Kiper
+---
+ 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 c3c4db1..a68e173 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;
+ }
+
diff --git a/grub/grub2/debian/patches/series b/grub/grub2/debian/patches/series
index def434d83..6c17adfd0 100644
--- a/grub/grub2/debian/patches/series
+++ b/grub/grub2/debian/patches/series
@@ -24,3 +24,5 @@
0024-loader-efi-chainloader-Simplify-the-loader-state.patch
0025-commands-boot-Add-API-to-pass-context-to-loader.patch
0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch
+0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
+0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch