]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
fs/ntfs: Track the end of the MFT attribute buffer
authorB Horn <b@horn.uk>
Tue, 7 Jan 2025 11:38:34 +0000 (11:38 +0000)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 23 Jan 2025 15:22:46 +0000 (16:22 +0100)
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 <b@horn.uk>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/fs/ntfs.c
include/grub/ntfs.h

index 8a5384247d79c6a819aeddf1602d34274619b1f7..dbda720e1ee9b8701ef45e735c57991846dd0c15 100644 (file)
@@ -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;
 }
@@ -811,7 +825,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);
@@ -842,7 +858,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;
@@ -1207,6 +1225,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);
 
@@ -1232,7 +1251,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))
index d1a6af6967fe256d331ed0b99635536aa41035ca..ec1c4db3833cf622c03c8ff100b9dacaee1230fa 100644 (file)
@@ -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;
 };