Rediffed
2009-03-22  Vladimir Serbinenko  <phco...@gmail.com>

      Leak fixes

      * kern/disk.c (grub_disk_cache_store): Invalidate previous cache
      in case of collision
      * disk/scsi.c (grub_scsi_open): free scsi in case of error


phcoder wrote:
Hello I discovered some memory leaks. Here is the fix
The main one was is that if a hash collision occurs new cache entry overwrites the old one but the old one wasn't freed. When loading a big file it was leaking huge amounts of memory



--

Regards
Vladimir 'phcoder' Serbinenko
diff --git a/disk/scsi.c b/disk/scsi.c
index 75b92b4..319d8d6 100644
--- a/disk/scsi.c
+++ b/disk/scsi.c
@@ -255,6 +255,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 	  scsi->name = grub_strdup (name);
 	  if (! scsi->name)
 	    {
+	      grub_free (scsi);
 	      return grub_errno;
 	    }
 
@@ -263,6 +264,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 	  err = grub_scsi_inquiry (scsi);
 	  if (err)
 	    {
+	      grub_free (scsi);
 	      grub_dprintf ("scsi", "inquiry failed\n");
 	      return grub_errno;
 	    }
@@ -275,6 +277,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 	  if (scsi->devtype != grub_scsi_devtype_direct
 	      && scsi->devtype != grub_scsi_devtype_cdrom)
 	    {
+	      grub_free (scsi);
 	      return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
 				 "unknown SCSI device");
 	    }
@@ -287,6 +290,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 	  err = grub_scsi_read_capacity (scsi);
 	  if (err)
 	    {
+	      grub_free (scsi);
 	      grub_dprintf ("scsi", "READ CAPACITY failed\n");
 	      return grub_errno;
 	    }
@@ -303,6 +307,8 @@ grub_scsi_open (const char *name, grub_disk_t disk)
 	}
     }
 
+  grub_free (scsi);
+
   return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
 }
 
diff --git a/kern/disk.c b/kern/disk.c
index 4ee03e0..8a92989 100644
--- a/kern/disk.c
+++ b/kern/disk.c
@@ -158,10 +158,13 @@ grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id,
   unsigned index;
   struct grub_disk_cache *cache;
   
-  grub_disk_cache_invalidate (dev_id, disk_id, sector);
-  
   index = grub_disk_cache_get_index (dev_id, disk_id, sector);
   cache = grub_disk_cache_table + index;
+ 
+  cache->lock = 1;
+  grub_free (cache->data);
+  cache->data = 0;
+  cache->lock = 0;
   
   cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
   if (! cache->data)
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to