From a7a440dc5425b03e0b754920d3b502dba6ebbd19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Thu, 20 Mar 2025 11:52:33 +0100 Subject: [PATCH] revert broken NTFS patches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NTFS is disabled with secure boot enabled anyway now, and these patches caused a regression both for grub during boot and grub_mount in userspace. Signed-off-by: Fabian Grünbichler --- .../0145-fs-ntfs-Fix-out-of-bounds-read.patch | 47 ---- ...-the-end-of-the-MFT-attribute-buffer.patch | 141 ---------- ...helper-function-to-access-attributes.patch | 197 -------------- ...tfs-Implement-attribute-verification.patch | 245 ------------------ ...lement-filesystem-reference-counting.patch | 4 +- ...able-many-filesystems-under-lockdown.patch | 6 +- ...e-consistent-overflow-error-messages.patch | 4 +- debian/patches/series | 4 - 8 files changed, 7 insertions(+), 641 deletions(-) delete mode 100644 debian/patches/cve_2025_02_multiple/0145-fs-ntfs-Fix-out-of-bounds-read.patch delete mode 100644 debian/patches/cve_2025_02_multiple/0146-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch delete mode 100644 debian/patches/cve_2025_02_multiple/0147-fs-ntfs-Use-a-helper-function-to-access-attributes.patch delete mode 100644 debian/patches/cve_2025_02_multiple/0148-fs-ntfs-Implement-attribute-verification.patch diff --git a/debian/patches/cve_2025_02_multiple/0145-fs-ntfs-Fix-out-of-bounds-read.patch b/debian/patches/cve_2025_02_multiple/0145-fs-ntfs-Fix-out-of-bounds-read.patch deleted file mode 100644 index 8d5376a45..000000000 --- a/debian/patches/cve_2025_02_multiple/0145-fs-ntfs-Fix-out-of-bounds-read.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Michael Chang -Date: Mon, 3 Jun 2024 12:12:06 +0800 -Subject: fs/ntfs: Fix out-of-bounds read - -When parsing NTFS file records the presence of the 0xFF marker indicates -the end of the attribute list. This value signifies that there are no -more attributes to process. - -However, when the end marker is missing due to corrupted metadata the -loop continues to read beyond the attribute list resulting in out-of-bounds -reads and potentially entering an infinite loop. - -This patch adds a check to provide a stop condition for the loop ensuring -it stops at the end of the attribute list or at the end of the Master File -Table. This guards against out-of-bounds reads and prevents infinite loops. - -Reported-by: Daniel Axtens -Signed-off-by: Michael Chang -Reviewed-by: Daniel Kiper -(cherry picked from commit aff26318783a135562b904ff09e2359893885732) ---- - grub-core/fs/ntfs.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index deb058a..976ad1d 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -139,6 +139,8 @@ free_attr (struct grub_ntfs_attr *at) - static grub_uint8_t * - find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - { -+ grub_uint8_t *mft_end; -+ - if (at->flags & GRUB_NTFS_AF_ALST) - { - retry: -@@ -191,7 +193,8 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - return NULL; - } - at->attr_cur = at->attr_nxt; -- while (*at->attr_cur != 0xFF) -+ 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); - if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) diff --git a/debian/patches/cve_2025_02_multiple/0146-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch b/debian/patches/cve_2025_02_multiple/0146-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch deleted file mode 100644 index 50b87233c..000000000 --- a/debian/patches/cve_2025_02_multiple/0146-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch +++ /dev/null @@ -1,141 +0,0 @@ -From: B Horn -Date: Tue, 7 Jan 2025 11:38:34 +0000 -Subject: fs/ntfs: Track the end of the MFT attribute buffer - -The end of the attribute buffer should be stored alongside the rest of -the attribute struct as right now it is not possible to implement bounds -checking when accessing attributes sequentially. - -This is done via: - - updating init_attr() to set at->end and check is is not initially out of bounds, - - implementing checks as init_attr() had its type change in its callers, - - updating the value of at->end when needed. - -Signed-off-by: B Horn -Reviewed-by: Daniel Kiper -(cherry picked from commit 237a71184a32d1ef7732f5f49ed6a89c5fe1c99a) ---- - grub-core/fs/ntfs.c | 34 ++++++++++++++++++++++++++++------ - include/grub/ntfs.h | 1 + - 2 files changed, 29 insertions(+), 6 deletions(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 976ad1d..562b4f7 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -119,13 +119,20 @@ static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, - grub_disk_read_hook_t read_hook, - void *read_hook_data); - --static void -+static grub_err_t - 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 + first_attr_off (mft->buf); -+ at->end = mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR); -+ -+ if (at->attr_nxt > at->end) -+ return grub_error (GRUB_ERR_BAD_FS, "attributes start outside the MFT"); -+ - at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; -+ -+ return GRUB_ERR_NONE; - } - - static void -@@ -239,6 +246,10 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - } - at->flags |= GRUB_NTFS_AF_ALST; -+ -+ /* From this point on pa_end is the end of the buffer */ -+ at->end = pa_end; -+ - while (at->attr_nxt < at->attr_end) - { - if ((*at->attr_nxt == attr) || (attr == 0)) -@@ -298,7 +309,9 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, - { - grub_uint8_t *pa; - -- init_attr (at, mft); -+ if (init_attr (at, mft) != GRUB_ERR_NONE) -+ return NULL; -+ - pa = find_attr (at, attr); - if (pa == NULL) - return NULL; -@@ -314,7 +327,8 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, - } - grub_errno = GRUB_ERR_NONE; - free_attr (at); -- init_attr (at, mft); -+ if (init_attr (at, mft) != GRUB_ERR_NONE) -+ return NULL; - pa = find_attr (at, attr); - } - return pa; -@@ -585,7 +599,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) - mft->attr.attr_end = 0; /* Don't jump to attribute list */ - } - else -- init_attr (&mft->attr, mft); -+ return init_attr (&mft->attr, mft); - - return 0; - } -@@ -807,7 +821,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - bmp = NULL; - - at = &attr; -- init_attr (at, mft); -+ if (init_attr (at, mft) != GRUB_ERR_NONE) -+ return 0; -+ - while (1) - { - cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT); -@@ -838,7 +854,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - bitmap = NULL; - bitmap_len = 0; - free_attr (at); -+ /* No need to check errors here, as it will already be fine */ - init_attr (at, mft); -+ - while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) - { - int ofs; -@@ -1203,6 +1221,7 @@ grub_ntfs_label (grub_device_t device, char **label) - struct grub_ntfs_data *data = 0; - struct grub_fshelp_node *mft = 0; - grub_uint8_t *pa; -+ grub_err_t err; - - grub_dl_ref (my_mod); - -@@ -1228,7 +1247,10 @@ grub_ntfs_label (grub_device_t device, char **label) - goto fail; - } - -- init_attr (&mft->attr, mft); -+ err = init_attr (&mft->attr, mft); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ - pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); - - if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h -index d1a6af6..ec1c4db 100644 ---- a/include/grub/ntfs.h -+++ b/include/grub/ntfs.h -@@ -134,6 +134,7 @@ struct grub_ntfs_attr - grub_uint8_t *attr_cur, *attr_nxt, *attr_end; - grub_uint32_t save_pos; - grub_uint8_t *sbuf; -+ grub_uint8_t *end; - struct grub_ntfs_file *mft; - }; - diff --git a/debian/patches/cve_2025_02_multiple/0147-fs-ntfs-Use-a-helper-function-to-access-attributes.patch b/debian/patches/cve_2025_02_multiple/0147-fs-ntfs-Use-a-helper-function-to-access-attributes.patch deleted file mode 100644 index 6eb0fc386..000000000 --- a/debian/patches/cve_2025_02_multiple/0147-fs-ntfs-Use-a-helper-function-to-access-attributes.patch +++ /dev/null @@ -1,197 +0,0 @@ -From: B Horn -Date: Tue, 14 May 2024 12:39:56 +0100 -Subject: fs/ntfs: Use a helper function to access attributes -MIME-Version: 1.0 -Content-Type: text/plain; charset="utf-8" -Content-Transfer-Encoding: 8bit - -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 -Reviewed-by: Daniel Kiper -(cherry picked from commit 048777bc29043403d077d41a81d0183767b8bc71) -FG: add missing stdbool.h include statement -Signed-off-by: Fabian Grünbichler ---- - grub-core/fs/ntfs.c | 71 +++++++++++++++++++++++++++++++++++++++++++---------- - include/grub/ntfs.h | 2 ++ - 2 files changed, 60 insertions(+), 13 deletions(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 562b4f7..56de4e6 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -19,6 +19,8 @@ - - #define grub_fshelp_node grub_ntfs_file - -+#include -+ - #include - #include - #include -@@ -70,6 +72,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 +172,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 +202,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 +245,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 +292,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 +320,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 +337,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 +574,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 ec1c4db..2c80784 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, diff --git a/debian/patches/cve_2025_02_multiple/0148-fs-ntfs-Implement-attribute-verification.patch b/debian/patches/cve_2025_02_multiple/0148-fs-ntfs-Implement-attribute-verification.patch deleted file mode 100644 index fb501bbaa..000000000 --- a/debian/patches/cve_2025_02_multiple/0148-fs-ntfs-Implement-attribute-verification.patch +++ /dev/null @@ -1,245 +0,0 @@ -From: B Horn -Date: Tue, 14 May 2024 12:39:56 +0100 -Subject: fs/ntfs: Implement attribute verification - -It was possible to read OOB when an attribute had a size that exceeded -the allocated buffer. This resolves that by making sure all attributes -that get read are fully in the allocated space by implementing -a function to validate them. - -Defining the offsets in include/grub/ntfs.h but they are only used in -the validation function and not across the rest of the NTFS code. - -Signed-off-by: B Horn -Reviewed-by: Daniel Kiper -(cherry picked from commit 067b6d225d482280abad03944f04e30abcbdafa1) ---- - grub-core/fs/ntfs.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - include/grub/ntfs.h | 22 ++++++++ - 2 files changed, 175 insertions(+) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 56de4e6..35e6c30 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -72,6 +72,149 @@ res_attr_data_len (void *res_attr_ptr) - return u32at (res_attr_ptr, 0x10); - } - -+/* -+ * Check if the attribute is valid and doesn't exceed the allocated region. -+ * This accounts for resident and non-resident data. -+ * -+ * This is based off the documentation from the linux-ntfs project: -+ * https://flatcap.github.io/linux-ntfs/ntfs/concepts/attribute_header.html -+ */ -+static bool -+validate_attribute (grub_uint8_t *attr, void *end) -+{ -+ grub_size_t attr_size = 0; -+ grub_size_t min_size = 0; -+ grub_size_t spare = (grub_uint8_t *) end - attr; -+ /* -+ * Just used as a temporary variable to try and deal with cases where someone -+ * tries to overlap fields. -+ */ -+ grub_size_t curr = 0; -+ -+ /* Need verify we can entirely read the attributes header. */ -+ if (attr + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end) -+ goto fail; -+ -+ /* -+ * So, the rest of this code uses a 16bit int for the attribute length but -+ * from reading the all the documentation I could find it says this field is -+ * actually 32bit. But let's be consistent with the rest of the code. -+ * -+ * https://elixir.bootlin.com/linux/v6.10.7/source/fs/ntfs3/ntfs.h#L370 -+ */ -+ attr_size = u16at (attr, GRUB_NTFS_ATTRIBUTE_LENGTH); -+ -+ if (attr_size > spare) -+ goto fail; -+ -+ /* Not an error case, just reached the end of the attributes. */ -+ if (attr_size == 0) -+ return false; -+ -+ /* -+ * Extra validation by trying to calculate a minimum possible size for this -+ * attribute. +8 from the size of the resident data struct which is the -+ * minimum that can be added. -+ */ -+ min_size = GRUB_NTFS_ATTRIBUTE_HEADER_SIZE + 8; -+ -+ if (min_size > attr_size) -+ goto fail; -+ -+ /* Is the data is resident (0) or not (1). */ -+ if (attr[GRUB_NTFS_ATTRIBUTE_RESIDENT] == 0) -+ { -+ /* Read the offset and size of the attribute. */ -+ curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_RES_OFFSET); -+ curr += u32at (attr, GRUB_NTFS_ATTRIBUTE_RES_LENGTH); -+ if (curr > min_size) -+ min_size = curr; -+ } -+ else -+ { -+ /* -+ * If the data is non-resident, the minimum size is 64 which is where -+ * the data runs start. We already have a minimum size of 24. So, just -+ * adding 40 to get to the real value. -+ */ -+ min_size += 40; -+ if (min_size > attr_size) -+ goto fail; -+ /* If the compression unit size is > 0, +8 bytes*/ -+ if (u16at (attr, GRUB_NTFS_ATTRIBUTE_COMPRESSION_UNIT_SIZE) > 0) -+ min_size += 8; -+ -+ /* -+ * Need to consider the data runs now. Each member of the run has byte -+ * that describes the size of the data length and offset. Each being -+ * 4 bits in the byte. -+ */ -+ curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_DATA_RUNS); -+ -+ if (curr + 1 > min_size) -+ min_size = curr + 1; -+ -+ if (min_size > attr_size) -+ goto fail; -+ -+ /* -+ * Each attribute can store multiple data runs which are stored -+ * continuously in the attribute. They exist as one header byte -+ * with up to 14 bytes following it depending on the lengths. -+ * We stop when we hit a header that is just a NUL byte. -+ * -+ * https://flatcap.github.io/linux-ntfs/ntfs/concepts/data_runs.html -+ */ -+ while (attr[curr] != 0) -+ { -+ /* -+ * We stop when we hit a header that is just a NUL byte. The data -+ * run header is stored as a single byte where the top 4 bits refer -+ * to the number of bytes used to store the total length of the -+ * data run, and the number of bytes used to store the offset. -+ * These directly follow the header byte, so we use them to update -+ * the minimum size. -+ */ -+ min_size += (attr[curr] & 0x7) + ((attr[curr] >> 4) & 0x7); -+ curr += min_size; -+ min_size++; -+ if (min_size > attr_size) -+ goto fail; -+ } -+ } -+ -+ /* Name offset, doing this after data residence checks. */ -+ if (u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET) != 0) -+ { -+ curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET); -+ /* -+ * Multiple the name length by 2 as its UTF-16. Can be zero if this in an -+ * unamed attribute. -+ */ -+ curr += attr[GRUB_NTFS_ATTRIBUTE_NAME_LENGTH] * 2; -+ if (curr > min_size) -+ min_size = curr; -+ } -+ -+ /* Padded to 8 bytes. */ -+ if (min_size % 8 != 0) -+ min_size += 8 - (min_size % 8); -+ -+ /* -+ * At this point min_size should be exactly attr_size but being flexible -+ * here to avoid any issues. -+ */ -+ if (min_size > attr_size) -+ goto fail; -+ -+ return true; -+ -+ fail: -+ grub_dprintf ("ntfs", "spare=%" PRIuGRUB_SIZE " min_size=%" PRIuGRUB_SIZE " attr_size=%" PRIuGRUB_SIZE "\n", -+ spare, min_size, attr_size); -+ return false; -+} -+ - /* Return the next attribute if it exists, otherwise return NULL. */ - static grub_uint8_t * - next_attribute (grub_uint8_t *curr_attribute, void *end) -@@ -86,6 +229,8 @@ next_attribute (grub_uint8_t *curr_attribute, void *end) - return NULL; - - next += u16at (curr_attribute, 4); -+ if (validate_attribute (next, end) == false) -+ return NULL; - - return next; - } -@@ -292,6 +437,9 @@ 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; - -+ if (validate_attribute (at->attr_nxt, pa_end) == false) -+ return NULL; -+ - while (at->attr_nxt) - { - if ((*at->attr_nxt == attr) || (attr == 0)) -@@ -321,6 +469,9 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - + 1)); - pa = at->attr_nxt + u16at (pa, 4); - -+ if (validate_attribute (pa, pa_end) == true) -+ pa = NULL; -+ - while (pa) - { - if (*pa != attr) -@@ -574,6 +725,8 @@ 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); -+ if (validate_attribute (pa, at->attr_end) == false) -+ pa = NULL; - - while (pa) - { -diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h -index 2c80784..77b182a 100644 ---- a/include/grub/ntfs.h -+++ b/include/grub/ntfs.h -@@ -91,6 +91,28 @@ enum - - #define GRUB_NTFS_ATTRIBUTE_HEADER_SIZE 16 - -+/* -+ * To make attribute validation clearer the offsets for each value in the -+ * attribute headers are defined as macros. -+ * -+ * These offsets are all from: -+ * https://flatcap.github.io/linux-ntfs/ntfs/concepts/attribute_header.html -+ */ -+ -+/* These offsets are part of the attribute header. */ -+#define GRUB_NTFS_ATTRIBUTE_LENGTH 4 -+#define GRUB_NTFS_ATTRIBUTE_RESIDENT 8 -+#define GRUB_NTFS_ATTRIBUTE_NAME_LENGTH 9 -+#define GRUB_NTFS_ATTRIBUTE_NAME_OFFSET 10 -+ -+/* Offsets for values needed for resident data. */ -+#define GRUB_NTFS_ATTRIBUTE_RES_LENGTH 16 -+#define GRUB_NTFS_ATTRIBUTE_RES_OFFSET 20 -+ -+/* Offsets for values needed for non-resident data. */ -+#define GRUB_NTFS_ATTRIBUTE_DATA_RUNS 32 -+#define GRUB_NTFS_ATTRIBUTE_COMPRESSION_UNIT_SIZE 34 -+ - enum - { - GRUB_NTFS_AF_ALST = 1, diff --git a/debian/patches/cve_2025_02_multiple/0156-kern-file-Implement-filesystem-reference-counting.patch b/debian/patches/cve_2025_02_multiple/0156-kern-file-Implement-filesystem-reference-counting.patch index 7624ecf90..0ca0f0610 100644 --- a/debian/patches/cve_2025_02_multiple/0156-kern-file-Implement-filesystem-reference-counting.patch +++ b/debian/patches/cve_2025_02_multiple/0156-kern-file-Implement-filesystem-reference-counting.patch @@ -246,10 +246,10 @@ index 3c248a9..c44583e 100644 my_mod = mod; } diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 35e6c30..4126c63 100644 +index deb058a..0ffcc9c 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c -@@ -1539,6 +1539,7 @@ static struct grub_fs grub_ntfs_fs = +@@ -1316,6 +1316,7 @@ static struct grub_fs grub_ntfs_fs = GRUB_MOD_INIT (ntfs) { diff --git a/debian/patches/cve_2025_02_multiple/0181-fs-Disable-many-filesystems-under-lockdown.patch b/debian/patches/cve_2025_02_multiple/0181-fs-Disable-many-filesystems-under-lockdown.patch index 4b657c22a..2141991f0 100644 --- a/debian/patches/cve_2025_02_multiple/0181-fs-Disable-many-filesystems-under-lockdown.patch +++ b/debian/patches/cve_2025_02_multiple/0181-fs-Disable-many-filesystems-under-lockdown.patch @@ -196,10 +196,10 @@ index c44583e..dd10c08 100644 + grub_fs_unregister (&grub_nilfs2_fs); } diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 4126c63..b1884ac 100644 +index 0ffcc9c..66ea467 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c -@@ -29,6 +29,7 @@ +@@ -27,6 +27,7 @@ #include #include #include @@ -207,7 +207,7 @@ index 4126c63..b1884ac 100644 GRUB_MOD_LICENSE ("GPLv3+"); -@@ -1539,12 +1540,16 @@ static struct grub_fs grub_ntfs_fs = +@@ -1316,12 +1317,16 @@ static struct grub_fs grub_ntfs_fs = GRUB_MOD_INIT (ntfs) { diff --git a/debian/patches/cve_2025_02_multiple/0199-misc-Ensure-consistent-overflow-error-messages.patch b/debian/patches/cve_2025_02_multiple/0199-misc-Ensure-consistent-overflow-error-messages.patch index 73ee282cf..215b0b531 100644 --- a/debian/patches/cve_2025_02_multiple/0199-misc-Ensure-consistent-overflow-error-messages.patch +++ b/debian/patches/cve_2025_02_multiple/0199-misc-Ensure-consistent-overflow-error-messages.patch @@ -15,10 +15,10 @@ Reviewed-by: Daniel Kiper 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index b1884ac..ec99331 100644 +index 66ea467..542b01e 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c -@@ -576,7 +576,7 @@ retry: +@@ -364,7 +364,7 @@ retry: goto retry; } } diff --git a/debian/patches/series b/debian/patches/series index 4e5ff274b..41d17a40c 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -142,10 +142,6 @@ cve_2025_02_multiple/0141-fs-jfs-Fix-OOB-read-caused-by-invalid-dir-slot-index.p cve_2025_02_multiple/0142-fs-jfs-Use-full-40-bits-offset-and-address-for-a-dat.patch cve_2025_02_multiple/0143-fs-jfs-Inconsistent-signed-unsigned-types-usage-in-r.patch cve_2025_02_multiple/0144-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch -cve_2025_02_multiple/0145-fs-ntfs-Fix-out-of-bounds-read.patch -cve_2025_02_multiple/0146-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch -cve_2025_02_multiple/0147-fs-ntfs-Use-a-helper-function-to-access-attributes.patch -cve_2025_02_multiple/0148-fs-ntfs-Implement-attribute-verification.patch cve_2025_02_multiple/0149-fs-xfs-Fix-issues-found-while-fuzzing-the-XFS-filesy.patch cve_2025_02_multiple/0150-fs-xfs-Incorrect-short-form-directory-data-boundary-.patch cve_2025_02_multiple/0151-fs-xfs-Fix-XFS-directory-extent-parsing.patch