This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/14609] New: Stack clobbering in pthread cancellation cleanup handlers
- From: "bugdal at aerifal dot cx" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: Sat, 22 Sep 2012 23:46:47 +0000
- Subject: [Bug nptl/14609] New: Stack clobbering in pthread cancellation cleanup handlers
- Auto-submitted: auto-generated
http://sourceware.org/bugzilla/show_bug.cgi?id=14609
Bug #: 14609
Summary: Stack clobbering in pthread cancellation cleanup
handlers
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: nptl
AssignedTo: unassigned@sourceware.org
ReportedBy: bugdal@aerifal.cx
CC: drepper.fsp@gmail.com
Classification: Unclassified
Created attachment 6650
--> http://sourceware.org/bugzilla/attachment.cgi?id=6650
test case demonstrating crash due to this bug
As they are specified in POSIX, cancellation cleanup handlers are simply
"invoked" when cancellation is acted upon, but nowhere is it specified that the
block scope of the function from which the cancellation point is called
terminates prematurely any time during the cleanup process, or that the block
scope of one cleanup push/pop is terminates before the next cleanup handler is
run. However, glibc's implementation of cleanup in terms of C++-style
exceptions results in cleanup handlers running as exceptions in the block where
they were installed, rather than merely being invoked. This means that objects
used by the cleanup handler may no longer exist at the time the cleanup handler
runs, and attempts to write to them will clobber the new stack frame in which
the cleanup handler is running.
I'm attaching a working proof-of-concept that demonstrates the issue by
clobbering its own stack and crashing, even though it has not done anything
that the POSIX standard disallows. It's rather ugly and unnatural since I wrote
it to ensure that the crash happens, not to mimic code that might appear in the
real world. A more real-world example is something like:
char small_bug[SMALL_SIZE];
struct context ctx = { .buf = small_buf };
pthread_cleanup_push(cleanup_func, &ctx);
...
if (...) {
char large_buf[LARGE_SIZE];
ctx->buf = large_buf;
...
ctx->buf = small_buf;
}
...
pthread_cleanup_pop(0);
I'm aware that this bug is inherent in the cancellation design glibc chose to
use, and is not easy to fix, but please do not mark this bug as invalid. If the
glibc team wants to be able to keep this behavior, a defect report process with
the Austin Group based on this glibc bug report should be started, with the
goal of making a rigorous definition of the interaction of cancellation cleanup
handlers and automatic object lifetimes, so that programs like my test case
become non-conforming in the next edition (or TC?) of POSIX.
Short of an amendment to the standard, I believe this bug report is valid.
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.