This is the mail archive of the glibc-bugs@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]

[Bug nptl/22563] __cancel_jmp_buf in __pthread_unwind_buf_t is incompatible with setjmp/longmp


https://sourceware.org/bugzilla/show_bug.cgi?id=22563

--- Comment #26 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, hjl/pr22743/master has been created
        at  d139cd31adaf9f091a36027c8a452b016a05e95c (commit)

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d139cd31adaf9f091a36027c8a452b016a05e95c

commit d139cd31adaf9f091a36027c8a452b016a05e95c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jan 24 15:27:49 2018 -0800

    nptl: Update struct pthread_unwind_buf [BZ #22743]

    In glibc 2.28, the size of cancel_jmp_buf in struct pthread_unwind_buf
    has been increased to match the size of __jmp_buf_tag on Linux/x86 in
    order to save and restore shadow stack register.  pthread_unwind_buf is
    used in <pthread.h>, whose address is passed from applications to
    libpthread.  To access the private data in struct pthread_unwind_buf,
    which is placed after cancel_jmp_buf, in libpthread, we must know which
    struct pthread_unwind_buf, before glibc 28 and after glibc 2.28, is used
    in caller.  If the size of caller's struct pthread_unwind_buf is smaller
    than what libpthread expects, libpthread will override caller's stack
    since struct pthread_unwind_buf is placed on caller's stack.

    We enable shadow stack at run-time only if program and all used shared
    objects, including dlopened ones, are shadow stack enabled, which means
    that they must be compiled with GCC 8 or above and glibc 2.28 or above.
    Since we need to save and restore shadow stack register only if shadow
    stack is enabled, we can safely assume that caller is compiled with
    smaller struct pthread_unwind_buf on stack if shadow stack isn't enabled
    at run-time.  For callers with larger struct pthread_unwind_buf, but
    shadow stack isn't enabled, we just have some unused space on caller's
    stack.

    struct pthread_unwind_buf is changed to union of

    1. struct cancel_jmp_buf[1], which contains the common fields of struct
    full and struct compat_pthread_unwind_buf.
    2. struct full_pthread_unwind_buf, which is the full layout of the
    cleanup buffer.
    3. struct compat_pthread_unwind_buf, which is the compatible layout of
    the cleanup buffer.

    A macro, UNWIND_BUF_PRIV, is added to get the pointer to the priv field.
    By default, it uses the priv field of struct compat_pthread_unwind_buf.
    If a target defines NEED_SAVED_MASK_IN_CANCEL_JMP_BUF, it must provide
    its own version of UNEIND_BUF_PRIV to get the pointer to the priv field.
    On Linux/x86, it uses the priv field of struct compat_pthread_unwind_buf
    if shadow stack is disabled and struct full_pthread_unwind_buf if shadow
    stack is enabled.

    Note: There is an unused pointer space in pthread_unwind_buf_data.  But
    it isn't unsuitable for saving and restoring shadow stack register since
    x32 is a 64-bit process with 32-bit software pointer and kernel may
    place x32 shadow stack above 4GB.  We need to save and restore 64-bit
    shadow stack register for x32.

        [BZ #22743]
        * csu/libc-start.c (LIBC_START_MAIN): Use the full version of
        the cleanup buffer.
        * nptl/cleanup.c (__pthread_register_cancel): Use UNWIND_BUF_PRIV
        to access the priv field in the cleanup buffer.
        (__pthread_unregister_cancel): Likewise.
        * nptl/cleanup_defer.c (__pthread_register_cancel_defer):
        Likewise.
        (__pthread_unregister_cancel_restore): Likewise.
        * nptl/unwind.c (unwind_stop): Likewise.
        (__pthread_unwind_next): Likewise.
        * nptl/descr.h (pthread_unwind_buf_data): New.
        (full_pthread_unwind_buf): Likewise.
        (compat_pthread_unwind_buf): Likewise.
        (pthread_unwind_buf): Updated to use full_pthread_unwind_buf
        and compat_pthread_unwind_buf.
        (UNWIND_BUF_PRIV): New.  Macro to get pointer to the priv field
        in the cleanup buffer.
        * nptl/pthread_create.c (START_THREAD_DEFN): Use the full
        version of the cleanup buffer.
        (__pthread_create_2_1): Use THREAD_COPY_ADDITONAL_INFO to copy
        additonal info if defined.
        * sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h: Use the full
        version of the cleanup buffer to check cancel_jmp_buf size.
        * sysdeps/unix/sysv/linux/x86/pthreaddef.h
        (THREAD_COPY_ADDITONAL_INFO): New.
        (UNWIND_BUF_PRIV): Likewise.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=048fc0aaf81cd328631b3485e348e3e5723cb826

commit 048fc0aaf81cd328631b3485e348e3e5723cb826
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Jan 26 05:19:15 2018 -0800

    Revert "Revert Intel CET changes to __jmp_buf_tag (Bug 22743)"

    This reverts commit 2ec0e7eade0ea1258acd5c6f5e5e9bfaeb5041a8.

    This is needed to save and restore shadow stack register in setjmp and
    longjmp.

        [BZ #22563]
        * sysdeps/i386/nptl/tcb-offsets.sym (FEATURE_1_OFFSET): New.
        * sysdeps/i386/nptl/tls.h (tcbhead_t): Add feature_1.
        * sysdeps/x86_64/nptl/tcb-offsets.sym (FEATURE_1_OFFSET): New.
        * sysdeps/x86_64/nptl/tls.h (tcbhead_t): Rename __glibc_unused1
        to feature_1.

        [BZ #22563]
        * bits/types/__cancel_jmp_buf_tag.h: New file.
        * sysdeps/unix/sysv/linux/x86/bits/types/__cancel_jmp_buf_tag.h
        * sysdeps/unix/sysv/linux/x86/pthreaddef.h: Likewise.
        * sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h: Likewise.
        * nptl/Makefile (headers): Add
        bits/types/__cancel_jmp_buf_tag.h.
        * nptl/descr.h [NEED_SAVED_MASK_IN_CANCEL_JMP_BUF]
        (pthread_unwind_buf): Add saved_mask to cancel_jmp_buf.
        * sysdeps/nptl/pthread.h: Include
        <bits/types/__cancel_jmp_buf_tag.h>.
        (__pthread_unwind_buf_t): Use struct __cancel_jmp_buf_tag with
        __cancel_jmp_buf.
        * sysdeps/unix/sysv/linux/hppa/pthread.h: Likewise.

-----------------------------------------------------------------------

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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