]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
fs/iso9660: Add check to prevent infinite loop
authorLidong Chen <lidong.chen@oracle.com>
Fri, 20 Jan 2023 19:39:38 +0000 (19:39 +0000)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 2 Feb 2023 18:43:50 +0000 (19:43 +0100)
There is no check for the end of block when reading
directory extents. It resulted in read_node() always
read from the same offset in the while loop, thus
caused infinite loop. The fix added a check for the
end of the block and ensure the read is within directory
boundary.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Thomas Schmitt <scdbackup@gmx.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/fs/iso9660.c

index df9f7783b42d4dc0faab2aac0f695b145bd0939c..24d84a56d6b4995032149b9dd3ed49388694d68c 100644 (file)
@@ -801,6 +801,16 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
        while (dirent.flags & FLAG_MORE_EXTENTS)
          {
            offset += dirent.len;
+
+           /* offset should within the dir's len. */
+           if (offset > len)
+             {
+               if (ctx.filename_alloc)
+                 grub_free (ctx.filename);
+               grub_free (node);
+               return 0;
+             }
+
            if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
              {
                if (ctx.filename_alloc)
@@ -808,6 +818,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
                grub_free (node);
                return 0;
              }
+
+           /*
+            * It is either the end of block or zero-padded sector,
+            * skip to the next block.
+            */
+           if (!dirent.len)
+             {
+               offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
+               dirent.flags |= FLAG_MORE_EXTENTS;
+               continue;
+             }
+
            if (node->have_dirents >= node->alloc_dirents)
              {
                struct grub_fshelp_node *new_node;