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] |
On 12/08/2017 03:25 AM, H.J. Lu wrote:
Here is call stack during stack unwind: (gdb) bt
(snip)
To unwind shadow stack, we need to save shadow stack pointer in __cancel_buf. This updated patch adds bits/types/__cancel_jmp_buf_tag.h to define struct __cancel_jmp_buf_tag so that Linux/x86 can add saved_mask to __cancel_jmp_buf. We will check if shadow stack is enabled before saving and restoring shadow stack pointer so that it works with the old smaller cancel_jmp_buf which doesn't have space for shadow stack pointer.
I still don't understand why you think you have to reset the shadow stack. I used this test program: #include <err.h> #include <errno.h> #include <pthread.h> #include <stdbool.h> #include <stdio.h> #include <unistd.h> __attribute__ ((noinline, noclone, weak)) void handler1 (void *closure) { printf ("handler1 called\n"); } __attribute__ ((noinline, noclone, weak)) void handler2 (void *closure) { printf ("handler2 called\n"); } __attribute__ ((noinline, noclone, weak)) void pausefunc (void) { while (true) pause (); } __attribute__ ((noinline, noclone, weak)) void handlerfunc (void) { pthread_cleanup_push (handler2, NULL); pausefunc (); pthread_cleanup_pop (1); } __attribute__ ((noinline, noclone, weak)) void * threadfunc (void *closure) { pthread_cleanup_push (handler1, NULL); handlerfunc (); pthread_cleanup_pop (0); return NULL; } int main (void) { pthread_t thr; int ret = pthread_create (&thr, NULL, threadfunc, NULL); if (ret != 0) { errno = ret; err (1, "pthread_create"); } ret = pthread_cancel (thr); if (ret != 0) { errno = ret; err (1, "pthread_cancel"); } void *result; ret = pthread_join (thr, &result); if (ret != 0) { errno = ret; err (1, "pthread_join"); } if (result != PTHREAD_CANCELED) errx (1, "pthread_join did not return PTHREAD_CANCEL, but %p", result); return 0; }See the attached GDB log. As you can see, I set breakpoints on all pre-existing RET instructions on the call stack (which would be protected by the shadow stack with CET). None of the RET instructions actually execute, ergo we do not have to restore the shadow stack.
Thanks, Florian
Attachment:
gdblog.txt
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |