[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: undefined behavior in closeout, aggravated by libsigsegv
From: |
Eric Blake |
Subject: |
Re: undefined behavior in closeout, aggravated by libsigsegv |
Date: |
Mon, 23 Nov 2009 17:27:35 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Eric Blake <ebb9 <at> byu.net> writes:
> > How can I reproduce it?
> Meanwhile, I will try to spend some time inspecting cygwin source code to
> see if I can find another example of an internal fault that cygwin expects
> to handle, and where libsigsegv intercepting the fault can cause
> observable behavior changes, beyond just EFAULT handling.
Here's a relatively simple example. POSIX 2001 states pthread_attr_init may
fail with EBUSY if an object was previously initialized. (Reliably testing
whether an object was previously initialized turns out to be a relatively hard
problem, so POSIX 2008 relaxed the specification by removing the 'may fail' of
EBUSY if x is already initialized, under the cop-out that such behavior was
already explicitly undefined, so an implementation may choose to do something
simpler than fail with EBUSY; however, in the rationale, it still states that
implementations are still encouraged to do an EBUSY check if feasible).
This example flushes out the libsigsegv interaction for both cygwin 1.5 and
today's CVS cygwin 1.7.
$ cat foo.c
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sigsegv.h>
int
handler (void *addr, int bad)
{
exit (2);
}
int main (int argc, char **argv)
{
pthread_attr_t a;
memset (&a, 1, sizeof a);
pthread_attr_init (&a);
if (1 < argc)
sigsegv_install_handler (handler);
pthread_attr_t b;
memset (&b, 1, sizeof b);
pthread_attr_init (&b);
return 0;
}
$ gcc -o foo -Wall -g foo.c -lsigsegv
$ ./foo; echo $?
0
$ ./foo 1; echo $?
2
The way that cygwin implements EBUSY validation is by probing the contents of
the pthread_attr_t to see if it is already initialized (that is, does the
pointer contain the magic cookie put in place during initialization and removed
during pthread_attr_destroy). But since the object can be stack-allocated, and
thus contain random bytes (simulated in the above example with the explicit
memset to make the example more repeatable), that probe can fault. In this
case, a fault is a GOOD thing - it means that the object is NOT already
initialized, so cygwin silently ignores the fault and lets pthread_attr_t
succeed. But if libsigsegv is compiled without --enable-EFAULT, it interferes
with POSIX compliance. Search for verifyable_object_isvalid in:
http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/thread.cc?
rev=1.216&content-type=text/x-cvsweb-markup&cvsroot=src
--
Eric Blake
- Re: undefined behavior in closeout, aggravated by libsigsegv, Bruno Haible, 2009/11/22
- Re: undefined behavior in closeout, aggravated by libsigsegv, Eric Blake, 2009/11/22
- Re: undefined behavior in closeout, aggravated by libsigsegv, Bruno Haible, 2009/11/22
- Re: undefined behavior in closeout, aggravated by libsigsegv, Eric Blake, 2009/11/22
- Re: undefined behavior in closeout, aggravated by libsigsegv, Eric Blake, 2009/11/22
- Re: undefined behavior in closeout, aggravated by libsigsegv, Bruno Haible, 2009/11/22