This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR7012, memory corruption in find_line


When looking at the patch provided in the PR to see whether it might be
freeing a NULL pointer (not all implementations of free accept a NULL),
I discovered some other nasty bugs.  I also couldn't convince myself
that is was safe to free dwarf_str_buffer and others without first
testing for NULL..

	PR 7012
	* dwarf2.c (find_line): Don't keep stale pointers into realloc'd
	memory.  Return on errors.  Fix memory leak.
	(_bfd_dwarf2_cleanup_debug_info): Free dwarf_str_buffer.

Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.114
diff -u -p -r1.114 dwarf2.c
--- bfd/dwarf2.c	8 Sep 2008 21:58:29 -0000	1.114
+++ bfd/dwarf2.c	10 Nov 2008 11:28:12 -0000
@@ -2989,8 +2989,6 @@ find_line (bfd *abfd,
 			      symbols, 0,
 			      &stash->info_ptr_memory, &total_size))
 	    goto done;
-	  stash->info_ptr = stash->info_ptr_memory;
-	  stash->info_ptr_end = stash->info_ptr + total_size;
 	}
       else
 	{
@@ -3008,63 +3006,64 @@ find_line (bfd *abfd,
 	      if (stash->info_ptr_memory == NULL)
 		goto done;
 
-	      stash->info_ptr = stash->info_ptr_memory;
-	      stash->info_ptr_end = stash->info_ptr;
-
+	      total_size = 0;
 	      for (msec = find_debug_info (debug_bfd, NULL);
 		   msec;
 		   msec = find_debug_info (debug_bfd, msec))
 		{
 		  bfd_size_type size;
-		  bfd_size_type start;
 
 		  size = msec->size;
 		  if (size == 0)
 		    continue;
 
-		  start = stash->info_ptr_end - stash->info_ptr;
-
-		  if ((bfd_simple_get_relocated_section_contents
-		       (debug_bfd, msec, stash->info_ptr + start, symbols))
-		      == NULL)
-		    continue;
+		  if (!(bfd_simple_get_relocated_section_contents
+			(debug_bfd, msec, stash->info_ptr_memory + total_size,
+			 symbols)))
+		    goto done;
 
-		  stash->info_ptr_end = stash->info_ptr + start + size;
+		  total_size += size;
 		}
-
-	      BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
 	    }
 	  else
 	    {
 	      /* Case 3: multiple sections, some or all compressed.  */
-	      stash->info_ptr_memory = bfd_malloc (1);
-	      stash->info_ptr = stash->info_ptr_memory;
-	      stash->info_ptr_end = stash->info_ptr;
+	      stash->info_ptr_memory = NULL;
+	      total_size = 0;
 	      for (msec = find_debug_info (debug_bfd, NULL);
 		   msec;
 		   msec = find_debug_info (debug_bfd, msec))
 		{
 		  bfd_size_type size = msec->size;
-		  bfd_byte* buffer
-		      = (bfd_simple_get_relocated_section_contents
-			 (debug_bfd, msec, NULL, symbols));
-		  if (! buffer)
+		  bfd_byte* buffer;
+
+		  if (size == 0)
 		    continue;
+
+		  buffer = (bfd_simple_get_relocated_section_contents
+			    (debug_bfd, msec, NULL, symbols));
+		  if (! buffer)
+		    goto done;
+
 		  if (strcmp (msec->name, DWARF2_COMPRESSED_DEBUG_INFO) == 0)
 		    {
 		      if (! bfd_uncompress_section_contents (&buffer, &size))
-			continue;
+			{
+			  free (buffer);
+			  goto done;
+			}
 		    }
-		  stash->info_ptr = bfd_realloc (stash->info_ptr,
-						 stash->info_ptr_end
-						 - stash->info_ptr + size);
-		  memcpy (stash->info_ptr_end, buffer, size);
+		  stash->info_ptr_memory = bfd_realloc (stash->info_ptr_memory,
+							total_size + size);
+		  memcpy (stash->info_ptr_memory + total_size, buffer, size);
 		  free (buffer);
-		  stash->info_ptr_end += size;
+		  total_size += size;
 		}
 	    }
 	}
 
+      stash->info_ptr = stash->info_ptr_memory;
+      stash->info_ptr_end = stash->info_ptr + total_size;
       stash->sec = find_debug_info (debug_bfd, NULL);
       stash->sec_info_ptr = stash->info_ptr;
       stash->syms = symbols;
@@ -3364,8 +3363,14 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abf
 	}
     }
 
-  free (stash->dwarf_abbrev_buffer);
-  free (stash->dwarf_line_buffer);
-  free (stash->dwarf_ranges_buffer);
-  free (stash->info_ptr_memory);
+  if (stash->dwarf_abbrev_buffer)
+    free (stash->dwarf_abbrev_buffer);
+  if (stash->dwarf_line_buffer)
+    free (stash->dwarf_line_buffer);
+  if (stash->dwarf_str_buffer)
+    free (stash->dwarf_str_buffer);
+  if (stash->dwarf_ranges_buffer)
+    free (stash->dwarf_ranges_buffer);
+  if (stash->info_ptr_memory)
+    free (stash->info_ptr_memory);
 }

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]