b1bcb2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b1bcb2
From: Darren Kenny <darren.kenny@oracle.com>
b1bcb2
Date: Thu, 26 Nov 2020 12:48:07 +0000
b1bcb2
Subject: [PATCH] affs: Fix memory leaks
b1bcb2
b1bcb2
The node structure reference is being allocated but not freed if it
b1bcb2
reaches the end of the function. If any of the hooks had returned
b1bcb2
a non-zero value, then node would have been copied in to the context
b1bcb2
reference, but otherwise node is not stored and should be freed.
b1bcb2
b1bcb2
Similarly, the call to grub_affs_create_node() replaces the allocated
b1bcb2
memory in node with a newly allocated structure, leaking the existing
b1bcb2
memory pointed by node.
b1bcb2
b1bcb2
Finally, when dir->parent is set, then we again replace node with newly
b1bcb2
allocated memory, which seems unnecessary when we copy in the values
b1bcb2
from dir->parent immediately after.
b1bcb2
b1bcb2
Fixes: CID 73759
b1bcb2
b1bcb2
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
b1bcb2
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
b1bcb2
---
b1bcb2
 grub-core/fs/affs.c | 18 ++++++++----------
b1bcb2
 1 file changed, 8 insertions(+), 10 deletions(-)
b1bcb2
b1bcb2
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
b1bcb2
index 91073795f90..e4615c74381 100644
b1bcb2
--- a/grub-core/fs/affs.c
b1bcb2
+++ b/grub-core/fs/affs.c
b1bcb2
@@ -400,12 +400,12 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
b1bcb2
 {
b1bcb2
   unsigned int i;
b1bcb2
   struct grub_affs_file file;
b1bcb2
-  struct grub_fshelp_node *node = 0;
b1bcb2
+  struct grub_fshelp_node *node, *orig_node;
b1bcb2
   struct grub_affs_data *data = dir->data;
b1bcb2
   grub_uint32_t *hashtable;
b1bcb2
 
b1bcb2
   /* Create the directory entries for `.' and `..'.  */
b1bcb2
-  node = grub_zalloc (sizeof (*node));
b1bcb2
+  node = orig_node = grub_zalloc (sizeof (*node));
b1bcb2
   if (!node)
b1bcb2
     return 1;
b1bcb2
     
b1bcb2
@@ -414,9 +414,6 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
b1bcb2
     return 1;
b1bcb2
   if (dir->parent)
b1bcb2
     {
b1bcb2
-      node = grub_zalloc (sizeof (*node));
b1bcb2
-      if (!node)
b1bcb2
-	return 1;
b1bcb2
       *node = *dir->parent;
b1bcb2
       if (hook ("..", GRUB_FSHELP_DIR, node, hook_data))
b1bcb2
 	return 1;
b1bcb2
@@ -456,17 +453,18 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
b1bcb2
 
b1bcb2
 	  if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable,
b1bcb2
 				     next, &file))
b1bcb2
-	    return 1;
b1bcb2
+	    {
b1bcb2
+	      /* Node has been replaced in function. */
b1bcb2
+	      grub_free (orig_node);
b1bcb2
+	      return 1;
b1bcb2
+	    }
b1bcb2
 
b1bcb2
 	  next = grub_be_to_cpu32 (file.next);
b1bcb2
 	}
b1bcb2
     }
b1bcb2
 
b1bcb2
-  grub_free (hashtable);
b1bcb2
-  return 0;
b1bcb2
-
b1bcb2
  fail:
b1bcb2
-  grub_free (node);
b1bcb2
+  grub_free (orig_node);
b1bcb2
   grub_free (hashtable);
b1bcb2
   return 0;
b1bcb2
 }