fs/xfs: Propagate incorrect inode error from grub_xfs_read_inode
authorEgor Ignatov <egori@altlinux.org>
Thu, 23 Jan 2025 17:44:15 +0000 (20:44 +0300)
committerFelix Zielcke <fzielcke@z-51.de>
Thu, 3 Jul 2025 16:35:51 +0000 (18:35 +0200)
The incorrect inode error from grub_xfs_read_inode did not propagate because
grub_print_error() resetted grub_errno, and grub_xfs_iterate_dir() did not
handle it at all.

Signed-off-by: Egor Ignatov <egori@altlinux.org>
Gbp-Pq: Topic cve-2025-jan
Gbp-Pq: Name fs-xfs-Propagate-incorrect-inode-error-from-grub_xfs_read.patch

grub-core/fs/xfs.c

index e0daeb45f8bb4fdc8ae562a2859f4178a3002180..28a34299690e768e56507e5767e8f7d404f98f0f 100644 (file)
@@ -806,7 +806,6 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
   fdiro = grub_malloc (sz);
   if (!fdiro)
     {
-      grub_print_error ();
       return 0;
     }
 
@@ -818,7 +817,6 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
   err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode);
   if (err)
     {
-      grub_print_error ();
       grub_free (fdiro);
       return 0;
     }
@@ -858,9 +856,13 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
        /* Synthesize the direntries for `.' and `..'.  */
        if (iterate_dir_call_hook (diro->ino, ".", &ctx))
          return 1;
+       else if (grub_errno)
+         return 0;
 
        if (iterate_dir_call_hook (parent, "..", &ctx))
          return 1;
+       else if (grub_errno)
+         return 0;
 
        for (i = 0; i < head->count &&
             (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++)
@@ -901,6 +903,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
              }
            de->name[de->len] = c;
 
+           if (grub_errno)
+             return 0;
+
            de = grub_xfs_inline_next_de(dir->data, head, de);
          }
        break;
@@ -998,6 +1003,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
                    grub_free (dirblock);
                    return 1;
                  }
+               else if (grub_errno)
+                 {
+                   grub_free (dirblock);
+                   return 0;
+                 }
 
                /*
                 * The expected number of directory entries is only tracked for the