d2fcd91
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d2fcd91
From: Maxim Suhanov <dfirblog@gmail.com>
d2fcd91
Date: Tue, 3 Oct 2023 19:12:24 +0200
d2fcd91
Subject: [PATCH] fs/ntfs: Fix an OOB read when reading data from the resident
d2fcd91
 $DATA attribute
d2fcd91
d2fcd91
When reading a file containing resident data, i.e., the file data is stored in
d2fcd91
the $DATA attribute within the NTFS file record, not in external clusters,
d2fcd91
there are no checks that this resident data actually fits the corresponding
d2fcd91
file record segment.
d2fcd91
d2fcd91
When parsing a specially-crafted file system image, the current NTFS code will
d2fcd91
read the file data from an arbitrary, attacker-chosen memory offset and of
d2fcd91
arbitrary, attacker-chosen length.
d2fcd91
d2fcd91
This allows an attacker to display arbitrary chunks of memory, which could
d2fcd91
contain sensitive information like password hashes or even plain-text,
d2fcd91
obfuscated passwords from BS EFI variables.
d2fcd91
d2fcd91
This fix implements a check to ensure that resident data is read from the
d2fcd91
corresponding file record segment only.
d2fcd91
d2fcd91
Fixes: CVE-2023-4693
d2fcd91
d2fcd91
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
d2fcd91
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
d2fcd91
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
d2fcd91
---
d2fcd91
 grub-core/fs/ntfs.c | 13 ++++++++++++-
d2fcd91
 1 file changed, 12 insertions(+), 1 deletion(-)
d2fcd91
d2fcd91
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
d2fcd91
index 4681c7ac32a8..1949d48a494f 100644
d2fcd91
--- a/grub-core/fs/ntfs.c
d2fcd91
+++ b/grub-core/fs/ntfs.c
d2fcd91
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
d2fcd91
     {
d2fcd91
       if (ofs + len > u32at (pa, 0x10))
d2fcd91
 	return grub_error (GRUB_ERR_BAD_FS, "read out of range");
d2fcd91
-      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
d2fcd91
+
d2fcd91
+      if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
d2fcd91
+	return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
d2fcd91
+
d2fcd91
+      if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
d2fcd91
+	return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
d2fcd91
+
d2fcd91
+      if (u16at (pa, 0x14) + u32at (pa, 0x10) >
d2fcd91
+	  (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
d2fcd91
+	return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
d2fcd91
+
d2fcd91
+      grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
d2fcd91
       return 0;
d2fcd91
     }
d2fcd91