[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);
}
#endif
@@ -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);
}
#endif