]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
fs/udf: Validate length of AED in grub_udf_read_block()
authorJagannathan Raman <jag.raman@oracle.com>
Thu, 17 Nov 2022 00:17:52 +0000 (00:17 +0000)
committerDaniel Kiper <daniel.kiper@oracle.com>
Wed, 7 Dec 2022 22:38:25 +0000 (23:38 +0100)
Validate the length of Allocation Extent Descriptor in grub_udf_read_block(),
based on the details in UDF spec. v2.01 section 2.3.11.

Fixes: CID 314037
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/fs/udf.c

index 12e88ab62ee119145366663333d72d79351d04ef..7679ea3098f9646731d98d7ba01c19f3b3adbc41 100644 (file)
@@ -510,6 +510,20 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
                }
 
              len = U32 (extension->ae_len);
+              /*
+               * Ensure AE length is less than block size
+               * per UDF spec v2.01 section 2.3.11.
+               *
+               * node->data->lbshift is initialized by
+               * grub_udf_mount(). lbshift has a maximum value
+               * of 3 and it does not cause an overflow here.
+               */
+              if (len < 0 || len > ((grub_ssize_t) 1 << node->data->lbshift))
+                {
+                  grub_error (GRUB_ERR_BAD_FS, "invalid ae length");
+                  goto fail;
+                }
+
              ad = (struct grub_udf_short_ad *)
                    (buf + sizeof (struct grub_udf_aed));
              continue;
@@ -563,6 +577,20 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
                }
 
              len = U32 (extension->ae_len);
+              /*
+               * Ensure AE length is less than block size
+               * per UDF spec v2.01 section 2.3.11.
+               *
+               * node->data->lbshift is initialized by
+               * grub_udf_mount(). lbshift has a maximum value
+               * of 3 and it does not cause an overflow here.
+               */
+              if (len < 0 || len > ((grub_ssize_t) 1 << node->data->lbshift))
+                {
+                  grub_error (GRUB_ERR_BAD_FS, "invalid ae length");
+                  goto fail;
+                }
+
              ad = (struct grub_udf_long_ad *)
                    (buf + sizeof (struct grub_udf_aed));
              continue;