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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> + Copyright (C) 2006, 2008 Bruno Haible <[EMAIL PROTECTED]> 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