This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 0/2] nptl: Update struct pthread_unwind_buf


* Carlos O'Donell:

> In the truncated sigjmp_buf used by pthread cancellation we have only 
> void * which is not large enough on x32, where you need a 64-bit
> shadow stack pointer. It would work on every other machine though.
> HJ has mentioned this problem already IIRC.
>
> Why would __pthread_register_cancel overwrite it?

__pthread_unwind_buf_t is defined as:

typedef struct
{
  struct
  {
    __jmp_buf __cancel_jmp_buf;
    int __mask_was_saved;
  } __cancel_jmp_buf[1];
  void *__pad[4];
} __pthread_unwind_buf_t __attribute__ ((__aligned__));

pthread_cleanup_push does this:

# define pthread_cleanup_push(routine, arg) \
  do {									      \
    __pthread_unwind_buf_t __cancel_buf;				      \
    void (*__cancel_routine) (void *) = (routine);			      \
    void *__cancel_arg = (arg);						      \
    int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)     \
					__cancel_buf.__cancel_jmp_buf, 0);    \
    if (__glibc_unlikely (__not_first_call))				      \
      {									      \
	__cancel_routine (__cancel_arg);				      \
	__pthread_unwind_next (&__cancel_buf);				      \
	/* NOTREACHED */						      \
      }									      \
									      \
    __pthread_register_cancel (&__cancel_buf);				      \
    do {

__pthread_register_cancel overwrites __cancel_buf.__pad.  If
__sigsetjmp were to write to that memory area, it would not matter, as
long as we skip restoring the shadow stack pointer during unwinding
(which we do not need to do because we never return along the regular
execution path recorded on the shadow stack).

In short, the only thing need to ensure is that the over-write from
__sigsetjmp stays within __cancel_buf.  Then we are good, without
changing the stack layout for cancellation.

My proposal is still rather hackish, but so is the existing code (the
truncated jump buffer), and HJ's approach of storing the shadow stack
pointer in the signal save area of the non-truncated jump buffer.  But
I think we can make it work.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]