Ada: fix potential SEGV when computing traceback on x86

Arnaud Charlet charlet@ACT-Europe.FR
Wed Oct 27 10:16:00 GMT 2004


Tested on x86-linux

In the case of i386 support, we were substracting some numbers from
ptr which was not null (check by the STOP_FRAME macro) the resulting pointer
could be equal or below 0 and a segmentation violation signal was raised
under e.g. Windows.
Note that there is no way to reproduce this problem with a small test case.

2004-10-26  Pascal Obry  <obry@gnat.com>

	* tracebak.c (IS_BAD_PTR): Use IsBadCodePtr on Win32 to check for ptr
	validity (process must have read access). Set to 0 in all other cases.
	(STOP_FRAME): Now check for ptr validity to avoid a segmentation
	violation on Win32.
	(VALID_STACK_FRAME): Check for ptr validity on Win32 to avoid a
	segmentation violation.

-------------- next part --------------
Index: tracebak.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/tracebak.c,v
retrieving revision 1.11
diff -u -p -r1.11 tracebak.c
--- tracebak.c	4 Oct 2004 15:02:29 -0000	1.11
+++ tracebak.c	27 Oct 2004 09:34:04 -0000
@@ -278,6 +278,13 @@ struct layout
 
 #elif defined (i386)
 
+#ifdef __WIN32
+#include <windows.h>
+#define IS_BAD_PTR(ptr) (IsBadCodePtr((void *)ptr))
+#else
+#define IS_BAD_PTR(ptr) 0
+#endif
+
 #define USE_GENERIC_UNWINDER
 
 struct layout
@@ -291,7 +298,8 @@ struct layout
 #define FRAME_OFFSET 0
 #define PC_ADJUST -2
 #define STOP_FRAME(CURRENT, TOP_STACK) \
-  ((unsigned int)(CURRENT)->return_address < LOWEST_ADDR \
+  (IS_BAD_PTR((long)(CURRENT)->return_address) \
+   || (unsigned int)(CURRENT)->return_address < LOWEST_ADDR \
    || (CURRENT)->return_address == 0|| (CURRENT)->next == 0  \
    || (void *) (CURRENT) < (TOP_STACK))
 
@@ -310,10 +318,11 @@ struct layout
 */
 
 #define VALID_STACK_FRAME(ptr) \
-   (((*((ptr) - 3) & 0xff) == 0xe8) \
-    || ((*((ptr) - 5) & 0xff) == 0x9a) \
-    || ((*((ptr) - 1) & 0xff) == 0xff) \
-    || (((*(ptr) & 0xd0ff) == 0xd0ff)))
+   (!IS_BAD_PTR(ptr) \
+    && (((*((ptr) - 3) & 0xff) == 0xe8) \
+        || ((*((ptr) - 5) & 0xff) == 0x9a) \
+        || ((*((ptr) - 1) & 0xff) == 0xff) \
+        || (((*(ptr) & 0xd0ff) == 0xd0ff))))
 
 /*------------------------------- mips-irix -------------------------------*/
 
@@ -324,7 +333,6 @@ struct layout
 
 #endif
 
-
 /*---------------------------------------------------------------------*
  *--      The post GCC 3.3 infrastructure based implementation       --*
  *---------------------------------------------------------------------*/


More information about the Gcc-patches mailing list