[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libsigsegv 2.5: bug in OpenBSD4.0

From: Eric Blake
Subject: Re: libsigsegv 2.5: bug in OpenBSD4.0
Date: Thu, 17 Jul 2008 14:43:57 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> When using both stackoverflow_install_handler and segv_handler_missing, a
> SIGSEGV from dereferencing NULL will be wrongly treated as a stack
> overflow on platforms that use mincore to check if the fault is near the
> stack.  In stackvma-mincore.c, mincore_is_near_this recognizes that
> computation of a target address in between the fault and the stack causes
> overflow, but then it calls is_unmapped(0,0) anyway.  Since the page
> containing 0 is unmapped, this results in claiming that a fault on NULL is
> treated as a fault near the stack, and the stack overflow handler is
> incorrectly invoked.

On the other hand, it looks like the following patch is better (at any rate, it 
matches the comments in the file).

Also, I think many of the stackvma-*.c files have async-safety bugs, which 
render them less than perfect for use in stack overflow detection.  For 
example, stackvma-procfs.c has a comment about why sigsegv_get_vma uses malloc
() instead of alloca(), but in the case of a stack overflow occurring during a 
previous malloc, you might cause deadlock by recursively invoking non-async-
safe malloc.  Likewise for stackvma-linux.c calling fscanf.  The libsigsegv 
testsuite is immune (it can get away with calling whatever it wants in the 
signal handler, since the stack overflow is not called by a non-async 
function), but it is much harder to make those same guarantees for a real-life 
program.  Technically, it might be possible to determine the worst-case stack 
depth of any non-recursive call chain that uses non-async-safe functions, then 
write the recursive functions to intentionally probe the stack out larger than 
that depth prior to invoking non-async functions, so that the stack overflow is 
then guaranteed to occur without interrupting a non-async function, but this is 
not trivial.

2008-07-17  Eric Blake  <address@hidden>

        Fix is_near_this logic to match comments.
        * src/stackvma-mincore.c (mincore_is_near_this): Use correct
        bounds to is_unmapped.
        * NEWS: Document the fix.

Index: NEWS
RCS file: /sources/libsigsegv/libsigsegv/NEWS,v
retrieving revision 1.16
diff -u -p -r1.16 NEWS
--- NEWS        28 May 2008 01:02:13 -0000      1.16
+++ NEWS        17 Jul 2008 14:43:15 -0000
@@ -1,6 +1,7 @@
 New in 2.6:
 * Support for 64-bit ABI on MacOS X 10.5.
+* Fix false positives in determining stack overflow when using mincore.
 New in 2.5:
Index: src/stackvma-mincore.c
RCS file: /sources/libsigsegv/libsigsegv/src/stackvma-mincore.c,v
retrieving revision 1.1
diff -u -p -r1.1 stackvma-mincore.c
--- src/stackvma-mincore.c      15 May 2006 12:01:12 -0000      1.1
+++ src/stackvma-mincore.c      17 Jul 2008 14:35:12 -0000
@@ -1,5 +1,5 @@
 /* Determine the virtual memory area of a given address.
-   Copyright (C) 2006  Bruno Haible <address@hidden>
+   Copyright (C) 2006, 2008  Bruno Haible <address@hidden>
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -227,7 +227,7 @@ mincore_is_near_this (unsigned long addr
   unsigned long testaddr = addr - (vma->start - addr);
   if (testaddr > addr) /* overflow? */
     testaddr = 0;
-  return is_unmapped (testaddr, addr);
+  return is_unmapped (testaddr, vma->start - 1);
@@ -246,7 +246,7 @@ mincore_is_near_this (unsigned long addr
   unsigned long testaddr = addr + (addr - vma->end);
   if (testaddr < addr) /* overflow? */
     testaddr = ~0UL;
-  return is_unmapped (addr, testaddr);
+  return is_unmapped (vma->end, testaddr);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]