This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[Patch] Fix memory corruption when using multiple hardware watchpoints.


In bpstat_stop_status there is special code to clear the breakpoint_at
element for a hardware watchpoint if it could be invalidated by a
remove_breakpoints(), insert_breakpoints() pair.  The comment explains
that we do this to "Prevent further code from trying to use it."

The problem with the current code is that it assumes that there is only
a single hardware breakpoint and breaks out of the loop when it is
found.  If there are multiple hardware breakpoints, any but the first
are left with breakpoint_at pointing at now freed memory leading to Bad
 Things if the memory happens to get clobbered.

My fix is to continue through the entire list clearing breakpoint_at for
 *all* hardware watchpoints and then outside of the loop calling
remove_breakpoints(), insert_breakpoints() if any were found.

Testing on x86_64-pc-linux-gnu.  OK to commit (if no regressions)?

2008-09-10  David Daney  <ddaney@avtrex.com>

	* breakpoint.c (bpstat_stop_status): Clear breakpoint_at for
	all hardware bpstats.
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.350
diff -u -p -r1.350 breakpoint.c
--- breakpoint.c	8 Sep 2008 21:57:42 -0000	1.350
+++ breakpoint.c	10 Sep 2008 19:56:58 -0000
@@ -3054,6 +3054,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
   int ix;
+  int need_remove_insert;
 
   ALL_BP_LOCATIONS (bl)
   {
@@ -3146,6 +3147,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
     if (bs->stop)
       break;
 
+  need_remove_insert = 0;
   if (bs == NULL)
     for (bs = root_bs->next; bs != NULL; bs = bs->next)
       if (!bs->stop
@@ -3158,11 +3160,15 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
 	     location is no longer used by the watchpoint.  Prevent
 	     further code from trying to use it.  */
 	  bs->breakpoint_at = NULL;
-	  remove_breakpoints ();
-	  insert_breakpoints ();
-	  break;
+	  need_remove_insert = 1;
 	}
 
+  if (need_remove_insert)
+    {
+      remove_breakpoints ();
+      insert_breakpoints ();
+    }
+
   return root_bs->next;
 }
 

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