bug-gnulib
[Top][All Lists]
Advanced

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

Re: determining the stack bounds


From: Eric Blake
Subject: Re: determining the stack bounds
Date: Fri, 06 Jun 2008 06:25:00 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080421 Thunderbird/2.0.0.14 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Bruno Haible on 6/6/2008 5:29 AM:
| The type of the third argument, according to POSIX, is 'void *ucp'. Why does
| it have to be cast? Why is it not directly 'ucontext_t *ucp' (since, as you
| say, ucontext_t will be defined in <signal.h>)?

I think POSIX is catering to the fact that older platforms (in particular
BSD) typed it as 'struct sigcontext *sc' instead.  More importantly,
ucontext_t is an XSI extension; you can be POSIX compliant but not XSI
compliant; in that case, you lack ucontext_t, and the third argument to a
sigaction handler must be an unusable void* (which is pretty much what I
discovered about OpenBSD 4.0).

|
|> The receiving thread may currently be in the alternate stack, but
|> the signal was delivered when the thread was still in the primary
stack.  So
|> maybe we should file this as a bug with the kernel folks, and hope that a
|> future version of Linux change uc_stack to supply the information we
want.
|> After all, we don't need uc_stack to learn about the current
(alternate) stack;
|> we can use sigaltstack() for that.
|
| I think you are misunderstanding things, and there is no Linux kernel
bug here.

Where would I even go to ask a Linux developer this question?

| When a signal S has been specified to execute on the alternate stack (via
| SA_ONSTACK), and SA_NODEFER is specified as well, when the signal S occurs a
| second time while the first signal occurrence is still being processed,
| the stack pointer cannot be set to the top of the alternating stack again -
| this room is already in use. So the second time the signal handling must
| behave as if there was no alternate stack. This is a semantic difference
| between the "context" of the main thread (where alternate signal stacks will
| be used when a signal occurs) and the "context" of signal handler (where
| alternate signal stacks will be ignored). This is why ucontext_t has a
| field 'uc_stack'.

I understand that - the ucontext_t of any secondary signals should
certainly be the alternate stack, because execution was interrupted while
the alternate stack was in use.  But I still claim that the _first_ segv
interrupted the main stack, and not the alternate stack; and it is the
first segv that I'm worried about.

|
| Whether sigaltstack(), when called during the signal handler, reports the
| existence of an alternate stack or not, is irrelevant. What matters, is the
| actual behaviour when a nested signal occurs.

And how we work around such behavior.

|
| Some systems (OpenBSD, IRIX, Solaris) store the fact that the alternate
stack
| is temporarily deactivated as a bit in the kernel. Others (Linux, MacOS X)
| determine it by looking whether the current stack pointer is in the range
| of the alternate stack.
|
| The description of 'uc_stack' in
http://www.opengroup.org/susv3/basedefs/ucontext.h.html
| is so vague that I would not base any program on it.

Yet that's exactly what c-stack is trying to do with
HAVE_XSI_STACK_OVERFLOW_HEURISTIC.

|> At any rate, the current implementation of c-stack precludes any
|> detection of non-stack overflow segv's on Linux (at least for the kernel
|> versions I was testing), because it claims ALL segvs are stack overflow,
|> whether or not that is true.
|
| Yes. Distinguishing between random SIGSEGV and stack overflow is a
feature that
| IMO is unique to libsigsegv.

So it looks like when libsigsegv is not compiled in, and uc_stack is not
reliable, then I'm down to a choice of c-stack's false positives
(reporting program bugs as stack overflow) instead of m4's false negatives
(reporting stack overflow as a program bug).

|
|> So c-stack could use a mincore()-like
|> capability to quickly determine whether all memory from the page near
the fault
|> over to the stack location saved at the time the handler was registered is
|> currently mapped (whether or not all of those pages are in core) (and
|> using /proc/self/maps when that is faster than mincore()).
|
| I agree with you that c-stack's use of 'uc_stack' is bogus, and on Linux,
| FreeBSD, OpenBSD, NetBSD, mincore() will give better results.

I guess I'll ask on the Austin group for some more ammunition as to
whether uc_stack is intended to be useful (whether or not current kernels
populate it with bogus data).

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkhJLJwACgkQ84KuGfSFAYARqACgp5xU+ErkqK/+XFdTSoldy5OV
GD8An1EhfhaUei83hFXfK0r2wWK6zJgv
=tf+C
-----END PGP SIGNATURE-----




reply via email to

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