public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* setjmp & longjmp at thread start & exit
@ 2020-06-23 14:42 Matthew Malcomson
  2020-06-23 16:33 ` Szabolcs Nagy
  0 siblings, 1 reply; 3+ messages in thread
From: Matthew Malcomson @ 2020-06-23 14:42 UTC (permalink / raw)
  To: libc-alpha

Hello

The pthread unwinding longjmp/setjmp setup seems a little confusing and
I'd like to ask about the viability of a change.

As I understand it there is a __libc_unwind_longjmp in unwind_stop that
either jumps to the non-interceptable setjmp in __libc_start_main, or to
the setjmp that can be intercepted which was called in the 
pthread_create.c function start_thread.

Is there anything requiring the non-interceptable setjmp in
__libc_start_main?
(Maybe something I don't know around dynamic linking at startup?)
If not, is there any chance of adding the PLT indirection to allow
interception?
I'm asking on the off-chance it's acceptable to the community, since I
do recognise intercepting setjmp & longjmp is not something user code
should usually be doing.


To explain why I'm asking:
I'm trying to handle longjmp and setjmp in a library that maintains a
shadow stack and I'm having trouble with these non-local jumps.
(hwasan -- hardware address sanitizer,
https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html).


To explain why I can't follow what ASAN does (which I expect would be
the first question on most people's minds):

ASAN intercepts all longjmp variants and no setjmp variants.
ASAN clears the entire shadow stack in these interceptors.  HWASAN can't
do the equivalent since it doesn't (in general) have a "valid" byte to
set on the shadow stack -- tags in the pointer used must match tags in
the shadow space.
(There *is* a HWASAN option to have a special match-all tag that's
always valid, but it's not the default and I wouldn't like require such
an approach for userspace santization with a GNU libc).


Thanks for any answers,
Matthew

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: setjmp & longjmp at thread start & exit
  2020-06-23 14:42 setjmp & longjmp at thread start & exit Matthew Malcomson
@ 2020-06-23 16:33 ` Szabolcs Nagy
  2020-06-24 10:06   ` Florian Weimer
  0 siblings, 1 reply; 3+ messages in thread
From: Szabolcs Nagy @ 2020-06-23 16:33 UTC (permalink / raw)
  To: Matthew Malcomson; +Cc: libc-alpha

The 06/23/2020 15:42, Matthew Malcomson wrote:
> Hello
> 
> The pthread unwinding longjmp/setjmp setup seems a little confusing and
> I'd like to ask about the viability of a change.
> 
> As I understand it there is a __libc_unwind_longjmp in unwind_stop that
> either jumps to the non-interceptable setjmp in __libc_start_main, or to
> the setjmp that can be intercepted which was called in the pthread_create.c
> function start_thread.
> 
> Is there anything requiring the non-interceptable setjmp in
> __libc_start_main?

jmp_buf layout is libc internal, only its size and
alignment is public abi. (i.e. layout may change
between glibc releases.)

so to intercept setjmp you have to ensure that all
public apis that rely on jmp_buf layout are intercepted.
(e.g. __siglongjmp or ___longjmp_chk are examples.)

and libc should continue to use its own jmp_buf apis
via interanl symbol names, not the intercepted symbols,
since it relies on its own jmp_buf layout (e.g. in
cancellation handling). i.e. you don't need PLT or
other indirection in libc.so: only intercept jmp_buf
apis in user code.

and this all only works if libc code is not instrumented
with hwasan and never jumps across user code when it uses
its internal jmpbuf apis. (i think this is guaranteed).

if you want to instrument glibc itself then you just
have to add hwasan support to it (without interception).

> (Maybe something I don't know around dynamic linking at startup?)
> If not, is there any chance of adding the PLT indirection to allow
> interception?
> I'm asking on the off-chance it's acceptable to the community, since I
> do recognise intercepting setjmp & longjmp is not something user code
> should usually be doing.
> 
> 
> To explain why I'm asking:
> I'm trying to handle longjmp and setjmp in a library that maintains a
> shadow stack and I'm having trouble with these non-local jumps.
> (hwasan -- hardware address sanitizer,
> https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html).
> 
> 
> To explain why I can't follow what ASAN does (which I expect would be
> the first question on most people's minds):
> 
> ASAN intercepts all longjmp variants and no setjmp variants.
> ASAN clears the entire shadow stack in these interceptors.  HWASAN can't
> do the equivalent since it doesn't (in general) have a "valid" byte to
> set on the shadow stack -- tags in the pointer used must match tags in
> the shadow space.
> (There *is* a HWASAN option to have a special match-all tag that's
> always valid, but it's not the default and I wouldn't like require such
> an approach for userspace santization with a GNU libc).

i think for hwasan you will need to add support
code into the libc.

and even then guaranteeing correct stack maintenance
may be difficult (e.g. swapcontext can switch to a
different stack or jump to a previous stackframe
and you may not be able to tell which happened.
or longjmp may jump out of a signal handler if that
interrupted signal-safe code, but the signal handler
stack may be different from the stack where longjump
lands, etc).

> 
> 
> Thanks for any answers,
> Matthew

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: setjmp & longjmp at thread start & exit
  2020-06-23 16:33 ` Szabolcs Nagy
@ 2020-06-24 10:06   ` Florian Weimer
  0 siblings, 0 replies; 3+ messages in thread
From: Florian Weimer @ 2020-06-24 10:06 UTC (permalink / raw)
  To: Szabolcs Nagy; +Cc: Matthew Malcomson, libc-alpha

* Szabolcs Nagy:

> if you want to instrument glibc itself then you just
> have to add hwasan support to it (without interception).

This is true for most of the sanitizers.  The interceptors break symbol
versioning and caller-sensitive functions such as dlopen and dlsym.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-06-24 10:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23 14:42 setjmp & longjmp at thread start & exit Matthew Malcomson
2020-06-23 16:33 ` Szabolcs Nagy
2020-06-24 10:06   ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).