grub2/0371-fs-ntfs-Use-a-helper-function-to-access-attributes.patch
Nicolas Frayer 6eaa34fe07 Add several CVE fixes
- Resolves: CVE-2024-45779 CVE-2024-45778 CVE-2025-1118
- Resolves: CVE-2025-0677 CVE-2024-45782 CVE-2025-0690
- Resolves: CVE-2024-45783 CVE-2025-0624 CVE-2024-45776
- Resolves: CVE-2025-0622 CVE-2024-45774 CVE-2024-45775
- Resolves: CVE-2024-45781 CVE-2024-45780
- Resolves: #RHEL-79700
- Resolves: #RHEL-79341
- Resolves: #RHEL-79875
- Resolves: #RHEL-79849
- Resolves: #RHEL-79707
- Resolves: #RHEL-79857
- Resolves: #RHEL-79709
- Resolves: #RHEL-79846
- Resolves: #RHEL-75737
- Resolves: #RHEL-79713
- Resolves: #RHEL-73785
- Resolves: #RHEL-73787
- Resolves: #RHEL-79704
- Resolves: #RHEL-79702

Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-02-18 19:06:15 +01:00

184 lines
5.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: B Horn <b@horn.uk>
Date: Tue, 14 May 2024 12:39:56 +0100
Subject: [PATCH] fs/ntfs: Use a helper function to access attributes
Right now to access the next attribute the code reads the length of the
current attribute and adds that to the current pointer. This is error
prone as bounds checking needs to be performed all over the place. So,
implement a helper and ensure its used across find_attr() and read_attr().
This commit does *not* implement full bounds checking. It is just the
preparation work for this to be added into the helper.
Signed-off-by: B Horn <b@horn.uk>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 69 +++++++++++++++++++++++++++++++++++++++++++----------
include/grub/ntfs.h | 2 ++
2 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index 562b4f7eb..9311ba9ef 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -70,6 +70,25 @@ res_attr_data_len (void *res_attr_ptr)
return u32at (res_attr_ptr, 0x10);
}
+/* Return the next attribute if it exists, otherwise return NULL. */
+static grub_uint8_t *
+next_attribute (grub_uint8_t *curr_attribute, void *end)
+{
+ grub_uint8_t *next = curr_attribute;
+
+ /*
+ * Need to verify we aren't exceeding the end of the buffer by reading the
+ * header for the current attribute
+ */
+ if (curr_attribute + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end)
+ return NULL;
+
+ next += u16at (curr_attribute, 4);
+
+ return next;
+}
+
+
grub_ntfscomp_func_t grub_ntfscomp_func;
static grub_err_t
@@ -151,13 +170,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
if (at->flags & GRUB_NTFS_AF_ALST)
{
retry:
- while (at->attr_nxt < at->attr_end)
+ while (at->attr_nxt)
{
at->attr_cur = at->attr_nxt;
- at->attr_nxt += u16at (at->attr_cur, 4);
+ at->attr_nxt = next_attribute (at->attr_cur, at->attr_end);
if ((*at->attr_cur == attr) || (attr == 0))
{
- grub_uint8_t *new_pos;
+ grub_uint8_t *new_pos, *end;
if (at->flags & GRUB_NTFS_AF_MMFT)
{
@@ -181,15 +200,36 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
return NULL;
}
+ /*
+ * Only time emft_bufs is defined is in this function, with this
+ * size.
+ */
+ grub_size_t emft_buf_size =
+ at->mft->data->mft_size << GRUB_NTFS_BLK_SHR;
+
+ /*
+ * Needs to be enough space for the successful case to even
+ * bother.
+ */
+ if (first_attr_off (at->emft_buf) >= (emft_buf_size - 0x18 - 2))
+ {
+ grub_error (GRUB_ERR_BAD_FS,
+ "can\'t find 0x%X in attribute list",
+ (unsigned char) *at->attr_cur);
+ return NULL;
+ }
+
new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
- while (*new_pos != 0xFF)
+ end = &at->emft_buf[emft_buf_size];
+
+ while (new_pos && *new_pos != 0xFF)
{
if ((*new_pos == *at->attr_cur)
&& (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
{
return new_pos;
}
- new_pos += u16at (new_pos, 4);
+ new_pos = next_attribute (new_pos, end);
}
grub_error (GRUB_ERR_BAD_FS,
"can\'t find 0x%X in attribute list",
@@ -203,7 +243,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
while (at->attr_cur < mft_end && *at->attr_cur != 0xFF)
{
- at->attr_nxt += u16at (at->attr_cur, 4);
+ at->attr_nxt = next_attribute (at->attr_cur, at->end);
if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
at->attr_end = at->attr_cur;
if ((*at->attr_cur == attr) || (attr == 0))
@@ -250,13 +290,14 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
/* From this point on pa_end is the end of the buffer */
at->end = pa_end;
- while (at->attr_nxt < at->attr_end)
+ while (at->attr_nxt)
{
if ((*at->attr_nxt == attr) || (attr == 0))
break;
- at->attr_nxt += u16at (at->attr_nxt, 4);
+ at->attr_nxt = next_attribute (at->attr_nxt, pa_end);
}
- if (at->attr_nxt >= at->attr_end)
+
+ if (at->attr_nxt >= at->attr_end || at->attr_nxt == NULL)
return NULL;
if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA))
@@ -277,7 +318,8 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
grub_cpu_to_le32 (at->mft->data->mft_start
+ 1));
pa = at->attr_nxt + u16at (pa, 4);
- while (pa < at->attr_end)
+
+ while (pa)
{
if (*pa != attr)
break;
@@ -293,7 +335,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0))
return NULL;
- pa += u16at (pa, 4);
+ pa = next_attribute (pa, pa_end);
}
at->attr_nxt = at->attr_cur;
at->flags &= ~GRUB_NTFS_AF_GPOS;
@@ -530,14 +572,15 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
else
vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR);
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
- while (pa < at->attr_end)
+
+ while (pa)
{
if (*pa != attr)
break;
if (u32at (pa, 8) > vcn)
break;
at->attr_nxt = pa;
- pa += u16at (pa, 4);
+ pa = next_attribute (pa, at->attr_end);
}
}
pp = find_attr (at, attr);
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
index ec1c4db38..2c8078403 100644
--- a/include/grub/ntfs.h
+++ b/include/grub/ntfs.h
@@ -89,6 +89,8 @@ enum
#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR)
#define GRUB_NTFS_LOG_COM_SEC (GRUB_NTFS_COM_LOG_LEN - GRUB_NTFS_BLK_SHR)
+#define GRUB_NTFS_ATTRIBUTE_HEADER_SIZE 16
+
enum
{
GRUB_NTFS_AF_ALST = 1,