This is the mail archive of the binutils@sources.redhat.com 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]

bad assumption in gas/stabs.c?



In s_stab_generic, we see code like this:

      string = demand_copy_C_string (&length);
...
#ifdef md_flush_pending_output
      md_flush_pending_output ();
#endif
...
	    obstack_free (&notes, string);

Now, in at least one case I saw, md_flush_pending_output called
symbol_new(), which used the notes obstack to allocate something, and
the obstack_free() freed more than just the string, which caused
memory corruption, and eventually an abort.

The documentation doesn't say md_flush_pending_output can't do that.

The attached patch guards against this case, but is there some better
solution?

2001-03-14  DJ Delorie  <dj@redhat.com>

	* stabs.c (s_stab_generic): Don't free the string if it's no
	longer at the top of the obstack.


Index: stabs.c
===================================================================
RCS file: /cvs/src/src/gas/stabs.c,v
retrieving revision 1.11
diff -p -3 -r1.11 stabs.c
*** stabs.c	2001/03/08 23:24:22	1.11
--- stabs.c	2001/03/14 22:54:01
*************** s_stab_generic (what, stab_secname, stab
*** 185,191 ****
       char *stabstr_secname;
  {
    long longint;
!   char *string;
    int type;
    int other;
    int desc;
--- 185,191 ----
       char *stabstr_secname;
  {
    long longint;
!   char *string, *saved_string_obstack_end;
    int type;
    int other;
    int desc;
*************** s_stab_generic (what, stab_secname, stab
*** 199,210 ****
       'd' indicating which type of .stab this is.  */
  
    if (what != 's')
!     string = "";
    else
      {
        int length;
  
        string = demand_copy_C_string (&length);
        SKIP_WHITESPACE ();
        if (*input_line_pointer == ',')
  	input_line_pointer++;
--- 199,214 ----
       'd' indicating which type of .stab this is.  */
  
    if (what != 's')
!     {
!       string = "";
!       saved_string_obstack_end = 0;
!     }
    else
      {
        int length;
  
        string = demand_copy_C_string (&length);
+       saved_string_obstack_end = notes.next_free;
        SKIP_WHITESPACE ();
        if (*input_line_pointer == ',')
  	input_line_pointer++;
*************** s_stab_generic (what, stab_secname, stab
*** 335,342 ****
        stroff = get_stab_string_offset (string, stabstr_secname);
        if (what == 's')
  	{
! 	  /* release the string */
! 	  obstack_free (&notes, string);
  	}
  
        /* At least for now, stabs in a special stab section are always
--- 339,347 ----
        stroff = get_stab_string_offset (string, stabstr_secname);
        if (what == 's')
  	{
! 	  /* Release the string, if nobody else has used the obstack.  */
! 	  if (saved_string_obstack_end == notes.next_free) 
! 	    obstack_free (&notes, string);
  	}
  
        /* At least for now, stabs in a special stab section are always


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