[glibc] Consolidate pointer guard to use a relro variable instead of the TCB
Adhemerval Zanella via Glibc-cvs <[email protected]> Tue, 16 Jun 2026 18:15:40 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a5ec880f808ee7268d985bed4f961799bdc0a4bf commit a5ec880f808ee7268d985bed4f961799bdc0a4bf Author: Adhemerval Zanella <[email protected]> Date: Fri Jun 12 13:10:10 2026 -0300 Consolidate pointer guard to use a relro variable instead of the TCB For the targets that still read the pointer guard from the thread descriptor (i386, x86_64, powerpc, s390, sparc, and sh), mangle and demangle pointers using the module-local __pointer_chk_guard_local (in ld.so and static binaries) or the global __pointer_chk_guard provided by the dynamic loader (in shared objects), matching the scheme already used by aarch64, alpha, arm, csky and loongarch. On i386 the guard is no longer reachable as a single %gs-relative memory operand, so the assembly PTR_MANGLE/PTR_DEMANGLE PIC variants need a register to hold the GOT pointer and the guard address. This removes the dependency on the TCB pointer_guard slot: drop THREAD_{GET,SET,COPY}_POINTER_GUARD and the POINTER_GUARD tcb-offset, and point the POINTER_CHK_GUARD test macro at the relro variable. The tcbhead_t slot is kept (renamed to an unused reserved field, except on s390 which reused the stack guard) to preserve the ABI. s390 gains a distinct pointer guard rather than aliasing the stack guard. Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and armv7a-linux-gnueabihf. I also run elf and setjmp checks on qemu loongarch64, powerpc64, powerpc64le, and s390x systems. Reviewed-by: DJ Delorie <[email protected]> Diff: --- sysdeps/arc/nptl/tls.h | 2 +- sysdeps/i386/__longjmp.S | 4 +- sysdeps/i386/bsd-_setjmp.S | 6 +-- sysdeps/i386/bsd-setjmp.S | 4 +- sysdeps/i386/htl/tcb-offsets.sym | 1 - sysdeps/i386/nptl/tcb-offsets.sym | 1 - sysdeps/i386/nptl/tls.h | 10 +--- sysdeps/i386/setjmp.S | 4 +- sysdeps/i386/stackguard-macros.h | 10 +++- sysdeps/mach/hurd/i386/tls.h | 9 +--- sysdeps/mach/hurd/x86_64/tls.h | 8 +--- sysdeps/powerpc/nptl/tcb-offsets.sym | 1 - sysdeps/powerpc/nptl/tls.h | 16 +------ sysdeps/powerpc/powerpc32/stackguard-macros.h | 16 +++---- sysdeps/powerpc/powerpc64/stackguard-macros.h | 16 +++---- sysdeps/s390/__longjmp.c | 2 +- sysdeps/s390/nptl/tls.h | 7 --- sysdeps/s390/stackguard-macros.h | 20 +++----- sysdeps/sh/nptl/tcb-offsets.sym | 1 - sysdeps/sh/nptl/tls.h | 15 +----- sysdeps/sh/stackguard-macros.h | 8 +++- sysdeps/sparc/nptl/tcb-offsets.sym | 1 - sysdeps/sparc/nptl/tls.h | 10 +--- sysdeps/sparc/sparc32/stackguard-macros.h | 9 +++- sysdeps/sparc/sparc64/stackguard-macros.h | 9 +++- sysdeps/unix/sysv/linux/i386/____longjmp_chk.S | 4 +- sysdeps/unix/sysv/linux/i386/pointer_guard.h | 53 +++++++++++++++++----- sysdeps/unix/sysv/linux/powerpc/pointer_guard.h | 53 ++++++++++++++++------ sysdeps/unix/sysv/linux/s390/pointer_guard.h | 33 +++++++++----- sysdeps/unix/sysv/linux/sh/pointer_guard.h | 53 ++++++++++++++++++---- .../unix/sysv/linux/sparc/sparc32/pointer_guard.h | 39 +++++++++++++--- .../unix/sysv/linux/sparc/sparc64/pointer_guard.h | 38 +++++++++++++--- sysdeps/unix/sysv/linux/x86_64/pointer_guard.h | 18 ++++---- sysdeps/x86_64/htl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tls.h | 10 +--- sysdeps/x86_64/stackguard-macros.h | 10 +++- 37 files changed, 303 insertions(+), 200 deletions(-) diff --git a/sysdeps/arc/nptl/tls.h b/sysdeps/arc/nptl/tls.h index 44862a32f3..38d61931bd 100644 --- a/sysdeps/arc/nptl/tls.h +++ b/sysdeps/arc/nptl/tls.h @@ -42,7 +42,7 @@ typedef struct { dtv_t *dtv; - uintptr_t pointer_guard; + uintptr_t __unused; } tcbhead_t; /* This is the size of the initial TCB. */ diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S index f188390fb5..c8f768d501 100644 --- a/sysdeps/i386/__longjmp.S +++ b/sysdeps/i386/__longjmp.S @@ -31,8 +31,8 @@ ENTRY (__longjmp) movl (JB_PC*4)(%eax), %edx /* Get the stack pointer. */ movl (JB_SP*4)(%eax), %ecx - PTR_DEMANGLE (%edx) - PTR_DEMANGLE (%ecx) + PTR_DEMANGLE (%edx, bx) + PTR_DEMANGLE (%ecx, bx) LIBC_PROBE (longjmp, 3, 4@%eax, -4@8(%esp), 4@%edx) cfi_def_cfa(%eax, 0) cfi_register(%eip, %edx) diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S index cb049be42f..8f509b7d51 100644 --- a/sysdeps/i386/bsd-_setjmp.S +++ b/sysdeps/i386/bsd-_setjmp.S @@ -31,7 +31,6 @@ ENTRY (_setjmp) - xorl %eax, %eax movl JMPBUF(%esp), %edx /* Save registers. */ @@ -40,17 +39,18 @@ ENTRY (_setjmp) movl %edi, (JB_DI*4)(%edx) leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, ax) #endif movl %ecx, (JB_SP*4)(%edx) movl 0(%esp), %ecx /* Save PC we are returning to now. */ LIBC_PROBE (setjmp, 3, 4@%edx, -4@$0, 4@%ecx) #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, ax) #endif movl %ecx, (JB_PC*4)(%edx) movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ + xorl %eax, %eax movl %eax, JB_SIZE(%edx) /* No signal mask set. */ ret END (_setjmp) diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S index 70336a119b..5f3a4694f3 100644 --- a/sysdeps/i386/bsd-setjmp.S +++ b/sysdeps/i386/bsd-setjmp.S @@ -42,13 +42,13 @@ ENTRY (setjmp) movl %edi, (JB_DI*4)(%eax) leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, dx) #endif movl %ecx, (JB_SP*4)(%eax) movl 0(%esp), %ecx /* Save PC we are returning to now. */ LIBC_PROBE (setjmp, 3, 4@%eax, -4@$1, 4@%ecx) #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, dx) #endif movl %ecx, (JB_PC*4)(%eax) movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ diff --git a/sysdeps/i386/htl/tcb-offsets.sym b/sysdeps/i386/htl/tcb-offsets.sym index 7b7c719369..b36cfd6848 100644 --- a/sysdeps/i386/htl/tcb-offsets.sym +++ b/sysdeps/i386/htl/tcb-offsets.sym @@ -4,5 +4,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate) diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym index 2ec9e787c1..48f7984512 100644 --- a/sysdeps/i386/nptl/tcb-offsets.sym +++ b/sysdeps/i386/nptl/tcb-offsets.sym @@ -11,6 +11,5 @@ SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) CLEANUP offsetof (struct pthread, cleanup) CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1) SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base) diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h index 87dcf5dc1f..fb8684230f 100644 --- a/sysdeps/i386/nptl/tls.h +++ b/sysdeps/i386/nptl/tls.h @@ -39,7 +39,7 @@ typedef struct int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; int gscope_flag; /* Bit 0: X86_FEATURE_1_IBT. Bit 1: X86_FEATURE_1_SHSTK. @@ -240,14 +240,6 @@ tls_fill_user_desc (union user_desc_init *desc, = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Set the pointer guard field in the TCB head. */ -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) - - /* Get and set the global scope generation counter in the TCB head. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/i386/setjmp.S b/sysdeps/i386/setjmp.S index 1cf1796040..8787be4ede 100644 --- a/sysdeps/i386/setjmp.S +++ b/sysdeps/i386/setjmp.S @@ -36,13 +36,13 @@ ENTRY (__sigsetjmp) movl %edi, (JB_DI*4)(%eax) leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, dx) #endif movl %ecx, (JB_SP*4)(%eax) movl 0(%esp), %ecx /* Save PC we are returning to now. */ LIBC_PROBE (setjmp, 3, 4@%eax, -4@SIGMSK(%esp), 4@%ecx) #ifdef PTR_MANGLE - PTR_MANGLE (%ecx) + PTR_MANGLE (%ecx, dx) #endif movl %ecx, (JB_PC*4)(%eax) movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h index 2939934ef1..696a977702 100644 --- a/sysdeps/i386/stackguard-macros.h +++ b/sysdeps/i386/stackguard-macros.h @@ -1,3 +1,11 @@ +#include <stdint.h> + #define STACK_CHK_GUARD (((tcbhead_t __seg_gs *)0)->stack_guard) -#define POINTER_CHK_GUARD (((tcbhead_t __seg_gs *)0)->pointer_guard) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h index 8cd643cdcf..403395db9a 100644 --- a/sysdeps/mach/hurd/i386/tls.h +++ b/sysdeps/mach/hurd/i386/tls.h @@ -36,7 +36,7 @@ typedef struct int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; int gscope_flag; unsigned int feature_1; /* Reservation of some values for the TM ABI. */ @@ -238,13 +238,6 @@ out: ((descr)->stack_guard \ = THREAD_GETMEM (THREAD_SELF, stack_guard)) -/* Set the pointer guard field in the TCB head. */ -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, pointer_guard, value) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, pointer_guard)) - # include <mach/machine/thread_status.h> diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h index 85ea75b5b5..3543e9be34 100644 --- a/sysdeps/mach/hurd/x86_64/tls.h +++ b/sysdeps/mach/hurd/x86_64/tls.h @@ -41,7 +41,7 @@ typedef struct int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; long __glibc_padding2[2]; int private_futex; int __glibc_padding3; @@ -125,12 +125,6 @@ THREAD_TCB (thread_t thread, ((descr)->stack_guard \ = THREAD_GETMEM (THREAD_SELF, stack_guard)) -/* Set the pointer guard field in the TCB head. */ -# define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, pointer_guard)) /* From hurd.h, reproduced here to avoid a circular include. */ extern thread_t __hurd_thread_self (void); diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym index 9b29fe8d1a..bc88ecdddb 100644 --- a/sysdeps/powerpc/nptl/tcb-offsets.sym +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym @@ -14,7 +14,6 @@ MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) #endif TID thread_offsetof (tid) -POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) TAR_SAVE (offsetof (tcbhead_t, tar_save) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) DSO_SLOT1 (offsetof (tcbhead_t, dso_slot1) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) DSO_SLOT2 (offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h index 4ef6dd1a2f..2e735c155b 100644 --- a/sysdeps/powerpc/nptl/tls.h +++ b/sysdeps/powerpc/nptl/tls.h @@ -60,8 +60,7 @@ /* The stack_guard is accessed directly by GCC -fstack-protector code, - so it is a part of public ABI. The dtv and pointer_guard fields - are private. */ + so it is a part of public ABI. The dtv field is private. */ typedef struct { /* Reservation for HWCAP3 and HWCAP4 data. To be accessed by GCC in @@ -96,7 +95,7 @@ typedef struct uintptr_t ebb_ctx_pointer; uintptr_t ebb_reserved1; uintptr_t ebb_reserved2; - uintptr_t pointer_guard; + uintptr_t __unused2; uintptr_t stack_guard; dtv_t *dtv; } tcbhead_t; @@ -186,17 +185,6 @@ extern tcbhead_t __tcb attribute_hidden; = ((tcbhead_t *) ((char *) __thread_register \ - TLS_TCB_OFFSET))[-1].stack_guard) -/* Set the stack guard field in TCB head. */ -# define THREAD_GET_POINTER_GUARD() \ - (((tcbhead_t *) ((char *) __thread_register \ - - TLS_TCB_OFFSET))[-1].pointer_guard) -# define THREAD_SET_POINTER_GUARD(value) \ - (THREAD_GET_POINTER_GUARD () = (value)) -# define THREAD_COPY_POINTER_GUARD(descr) \ - (((tcbhead_t *) ((char *) (descr) \ - + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ - = THREAD_GET_POINTER_GUARD()) - /* hwcap & hwcap_extn fields in TCB head. */ # define THREAD_GET_HWCAP() \ (((tcbhead_t *) ((char *) __thread_register \ diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h index b3d0af830f..0c94269a73 100644 --- a/sysdeps/powerpc/powerpc32/stackguard-macros.h +++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h @@ -3,12 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - asm ("lwz %0,%1(2)" \ - : "=r" (x) \ - : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ - ); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h index e80a683e64..fec2e69f64 100644 --- a/sysdeps/powerpc/powerpc64/stackguard-macros.h +++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h @@ -3,12 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - asm ("ld %0,%1(13)" \ - : "=r" (x) \ - : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ - ); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c index 7c207e44c6..78aa70a943 100644 --- a/sysdeps/s390/__longjmp.c +++ b/sysdeps/s390/__longjmp.c @@ -35,7 +35,7 @@ void __longjmp (__jmp_buf env, int val) { #ifdef PTR_DEMANGLE - uintptr_t guard = THREAD_GET_POINTER_GUARD (); + uintptr_t guard = PTR_GUARD_VALUE; # ifdef CHECK_SP CHECK_SP (env, guard); # endif diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h index de7e9c6482..41fd473d14 100644 --- a/sysdeps/s390/nptl/tls.h +++ b/sysdeps/s390/nptl/tls.h @@ -139,13 +139,6 @@ typedef struct ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* s390 doesn't have HP_TIMING_*, so for the time being - use stack_guard as pointer_guard. */ -#define THREAD_GET_POINTER_GUARD() \ - THREAD_GETMEM (THREAD_SELF, header.stack_guard) -#define THREAD_SET_POINTER_GUARD(value) ((void) (value)) -#define THREAD_COPY_POINTER_GUARD(descr) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/s390/stackguard-macros.h b/sysdeps/s390/stackguard-macros.h index 3671c7cd7a..22e4751a73 100644 --- a/sysdeps/s390/stackguard-macros.h +++ b/sysdeps/s390/stackguard-macros.h @@ -3,16 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; __asm__ ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; }) -/* On s390x there is no unique pointer guard, instead we use the - same value as the stack guard. */ -#define POINTER_CHK_GUARD \ - ({ \ - uintptr_t x; \ - __asm__ ("ear %0,%%a0;" \ - "sllg %0,%0,32;" \ - "ear %0,%%a1;" \ - "lg %0,%1(%0)" \ - : "=a" (x) \ - : "i" (offsetof (tcbhead_t, stack_guard))); \ - x; \ - }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym index 234207779d..f1da9a0515 100644 --- a/sysdeps/sh/nptl/tcb-offsets.sym +++ b/sysdeps/sh/nptl/tcb-offsets.sym @@ -9,4 +9,3 @@ CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf) MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) TLS_PRE_TCB_SIZE sizeof (struct pthread) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h index eac95e14c7..7008003344 100644 --- a/sysdeps/sh/nptl/tls.h +++ b/sysdeps/sh/nptl/tls.h @@ -33,7 +33,7 @@ typedef struct { dtv_t *dtv; - uintptr_t pointer_guard; + uintptr_t __unused; } tcbhead_t; # define TLS_MULTIPLE_THREADS_IN_TCB 1 @@ -109,19 +109,6 @@ typedef struct # include <tcb-access.h> -#define THREAD_GET_POINTER_GUARD() \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - __tcbp->pointer_guard;}) - #define THREAD_SET_POINTER_GUARD(value) \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - __tcbp->pointer_guard = (value);}) -#define THREAD_COPY_POINTER_GUARD(descr) \ - ({ tcbhead_t *__tcbp; \ - __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ - ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;}) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/sh/stackguard-macros.h b/sysdeps/sh/stackguard-macros.h index 55a5771b62..b4a6b23ff8 100644 --- a/sysdeps/sh/stackguard-macros.h +++ b/sysdeps/sh/stackguard-macros.h @@ -3,4 +3,10 @@ extern uintptr_t __stack_chk_guard; #define STACK_CHK_GUARD __stack_chk_guard -#define POINTER_CHK_GUARD THREAD_GET_POINTER_GUARD() +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym index f75d02065e..a64180da03 100644 --- a/sysdeps/sparc/nptl/tcb-offsets.sym +++ b/sysdeps/sparc/nptl/tcb-offsets.sym @@ -2,5 +2,4 @@ #include <tls.h> MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) TID offsetof (struct pthread, tid) diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h index cd2112a650..361fc11a43 100644 --- a/sysdeps/sparc/nptl/tls.h +++ b/sysdeps/sparc/nptl/tls.h @@ -41,7 +41,7 @@ typedef struct #endif uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; #if __WORDSIZE != 64 int gscope_flag; #endif @@ -115,14 +115,6 @@ register struct pthread *__thread_self __asm__("%g7"); ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Get/set the stack guard field in TCB head. */ -#define THREAD_GET_POINTER_GUARD() \ - THREAD_GETMEM (THREAD_SELF, header.pointer_guard) -#define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ()) - /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h index 1eef0f19f0..e8000a2899 100644 --- a/sysdeps/sparc/sparc32/stackguard-macros.h +++ b/sysdeps/sparc/sparc32/stackguard-macros.h @@ -3,5 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ld [%%g7+0x14], %0" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ uintptr_t x; asm ("ld [%%g7+0x18], %0" : "=r" (x)); x; }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h index cc0c12c041..99978d8bec 100644 --- a/sysdeps/sparc/sparc64/stackguard-macros.h +++ b/sysdeps/sparc/sparc64/stackguard-macros.h @@ -3,5 +3,10 @@ #define STACK_CHK_GUARD \ ({ uintptr_t x; asm ("ldx [%%g7+0x28], %0" : "=r" (x)); x; }) -#define POINTER_CHK_GUARD \ - ({ uintptr_t x; asm ("ldx [%%g7+0x30], %0" : "=r" (x)); x; }) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S index c7573fe927..aea4d156f7 100644 --- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -52,8 +52,8 @@ ENTRY (____longjmp_chk) /* Get the stack pointer. */ movl (JB_SP*4)(%ecx), %edi cfi_undefined(%edi) - PTR_DEMANGLE (%edx) - PTR_DEMANGLE (%edi) + PTR_DEMANGLE (%edx, bx) + PTR_DEMANGLE (%edi, bx) cmpl %edi, %esp jbe .Lok diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h index c8311be444..27fa8de465 100644 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h @@ -19,26 +19,56 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#include <tcb-offsets.h> - #if IS_IN (rtld) /* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. Using a global variable - is too complicated here since we have no PC-relative addressing mode. */ + earlier than the descriptor is initialized. */ # include <sysdeps/generic/pointer_guard.h> #else # ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xorl %gs:POINTER_GUARD, reg; \ +# include <sysdep.h> +/* The PIC variants clobber TMP, a register name suffix as expected by + LOAD_PIC_REG (e.g. dx for %edx), to load the guard value. */ +# ifdef SHARED +/* The global guard is reached through the GOT. */ +# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \ + movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ + xorl (%e##tmp), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg, tmp) \ + rorl $9, reg; \ + LOAD_PIC_REG (tmp); \ + movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ + xorl (%e##tmp), reg +# elif defined PIC +/* Static PIE: the module-local guard is reached via @GOTOFF. */ +# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \ + xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg, tmp) \ + rorl $9, reg; \ + LOAD_PIC_REG (tmp); \ + xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg +# else +/* Position-dependent code addresses the guard directly. */ +# define PTR_MANGLE(reg, tmp) xorl __pointer_chk_guard_local, reg; \ roll $9, reg -# define PTR_DEMANGLE(reg) rorl $9, reg; \ - xorl %gs:POINTER_GUARD, reg +# define PTR_DEMANGLE(reg, tmp) \ + rorl $9, reg; \ + xorl __pointer_chk_guard_local, reg +# endif # else # include <stdbit.h> -# include <tls.h> +# include <stdint.h> +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# endif # define PTR_MANGLE(var) \ do { \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) @@ -46,8 +76,7 @@ do { \ (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ - (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_gs *)0)->pointer_guard); \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ } while (0) # endif #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h index 50d177224f..864a78ea53 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h @@ -20,34 +20,59 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ # include <sysdeps/generic/pointer_guard.h> #else # ifdef __ASSEMBLER__ +# include <sysdep.h> +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif + # if defined(__PPC64__) || defined(__powerpc64__) -# define LOAD ld -# define TPREG r13 +# define PTR_GUARD_LOAD(tmpreg) \ + addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ + ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ + ld tmpreg,0(tmpreg) +# elif defined PIC +# define PTR_GUARD_LOAD(tmpreg) \ + mflr r12; \ + bcl 20,31,0f; \ +0: mflr tmpreg; \ + addis tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@ha; \ + addi tmpreg,tmpreg,_GLOBAL_OFFSET_TABLE_-0b@l; \ + mtlr r12; \ + lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ + lwz tmpreg,0(tmpreg) # else -# define LOAD lwz -# define TPREG r2 +# define PTR_GUARD_LOAD(tmpreg) \ + lis tmpreg,PTR_GUARD_SYM@ha; \ + lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) # endif + # define PTR_MANGLE(reg, tmpreg) \ - LOAD tmpreg,POINTER_GUARD(TPREG); \ - xor reg,tmpreg,reg + PTR_GUARD_LOAD (tmpreg); \ + xor reg,tmpreg,reg # define PTR_MANGLE2(reg, tmpreg) \ - xor reg,tmpreg,reg + xor reg,tmpreg,reg # define PTR_MANGLE3(destreg, reg, tmpreg) \ - LOAD tmpreg,POINTER_GUARD(TPREG); \ - xor destreg,tmpreg,reg + PTR_GUARD_LOAD (tmpreg); \ + xor destreg,tmpreg,reg # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) # define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) # define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) # else # include <stdint.h> -# include <tls.h> -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h index d7a574e94c..aa75b8c42e 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h @@ -20,26 +20,37 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ # include <sysdeps/generic/pointer_guard.h> #else -/* For the time being just use stack_guard rather than a separate - pointer_guard. */ # ifdef __ASSEMBLER__ +# ifdef SHARED +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard@GOTENT; \ + lg tmpreg,0(tmpreg); \ + lg tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard_local; \ + lg tmpreg,0(tmpreg) +# endif # define PTR_MANGLE(reg, tmpreg) \ - ear tmpreg,%a0; \ - sllg tmpreg,tmpreg,32; \ - ear tmpreg,%a1; \ - xg reg,STACK_GUARD(tmpreg) + PTR_GUARD_LOAD (tmpreg); \ + xgr reg,tmpreg # define PTR_MANGLE2(reg, tmpreg) \ - xg reg,STACK_GUARD(tmpreg) + xgr reg,tmpreg # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) # else # include <stdint.h> -# include <tls.h> +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# endif # define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) + (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h index f1ec4b41f4..fa989573c9 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h @@ -1,4 +1,4 @@ -/* Pointer obfuscation implenentation. Generic (no-op) version. +/* Pointer obfuscation implenentation. SH version. Copyright (C) 2005-2026 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -20,22 +20,59 @@ #define POINTER_GUARD_H #if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. Using a global variable - is too complicated here since we have no PC-relative addressing mode. */ # include <sysdeps/generic/pointer_guard.h> #else # ifdef __ASSEMBLER__ +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +# define PTR_GUARD_LOAD(tmp) \ + mov r0, r3; \ + mova .Lptrg_got, r0; \ + mov.l .Lptrg_got, tmp; \ + add r0, tmp; \ + mov.l .Lptrg_sym, r0; \ + mov.l @(r0, tmp), tmp; \ + mov r3, r0; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_got: \ + .long _GLOBAL_OFFSET_TABLE_; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM@GOT; \ +.Lptrg_end: +# else +# define PTR_GUARD_LOAD(tmp) \ + mov.l .Lptrg_sym, tmp; \ + mov.l @tmp, tmp; \ + bra .Lptrg_end; \ + nop; \ + .align 2; \ +.Lptrg_sym: \ + .long PTR_GUARD_SYM; \ +.Lptrg_end: +# endif # define PTR_MANGLE(reg, tmp) \ - stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg + PTR_GUARD_LOAD (tmp); xor tmp,reg # define PTR_MANGLE2(reg, tmp) xor tmp,reg # define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) # define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) # else # include <stdint.h> -# include <tls.h> -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h index 4359bf9fca..f314f8598b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h @@ -25,18 +25,45 @@ # include <sysdeps/generic/pointer_guard.h> #else # ifdef __ASSEMBLER__ +# include <sysdep.h> +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT + pointer in %o2 while preserving %o7 (the return address, which setjmp + mangles), using %o3 as a scratch register. */ +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ld [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif # define PTR_MANGLE(dreg, reg, tmpreg) \ - ld [%g7 + POINTER_GUARD], tmpreg; \ - xor reg, tmpreg, dreg + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg # define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) # define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg + xor reg, tmpreg, dreg # define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) # else # include <stdint.h> -# include <tls.h> -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h index 91bc1f4d85..6515e0dd07 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h @@ -25,18 +25,44 @@ # include <sysdeps/generic/pointer_guard.h> #else # ifdef __ASSEMBLER__ +# include <sysdep.h> +# ifdef SHARED +# define PTR_GUARD_SYM __pointer_chk_guard +# else +# define PTR_GUARD_SYM __pointer_chk_guard_local +# endif +# ifdef PIC +/* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT + pointer in %o2 while preserving %o7, using %o3 as a scratch register. */ +# define PTR_GUARD_LOAD(tmpreg) \ + SETUP_PIC_REG_LEAF(o2, o3); \ + sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ + xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ + ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ + ldx [tmpreg], tmpreg +# else +# define PTR_GUARD_LOAD(tmpreg) \ + sethi %hi(PTR_GUARD_SYM), tmpreg; \ + ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg +# endif # define PTR_MANGLE(dreg, reg, tmpreg) \ - ldx [%g7 + POINTER_GUARD], tmpreg; \ - xor reg, tmpreg, dreg + PTR_GUARD_LOAD (tmpreg); \ + xor reg, tmpreg, dreg # define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) # define PTR_MANGLE2(dreg, reg, tmpreg) \ - xor reg, tmpreg, dreg + xor reg, tmpreg, dreg # define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) # else # include <stdint.h> -# include <tls.h> -# define PTR_MANGLE(var) \ - (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# ifdef SHARED +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# endif # define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif #endif diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h index 4f7abc64f4..6d09b429cd 100644 --- a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h @@ -22,9 +22,8 @@ #include <x86-lp_size.h> #include <tcb-offsets.h> -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ +#if (IS_IN (rtld) \ + || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) # ifdef __ASSEMBLER__ # define PTR_MANGLE(reg) xor __pointer_chk_guard_local(%rip), reg; \ rol $2*LP_SIZE+1, reg @@ -51,17 +50,20 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; # endif #else # ifdef __ASSEMBLER__ -# define PTR_MANGLE(reg) xor %fs:POINTER_GUARD, reg; \ +# define PTR_MANGLE(reg) mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ + xor (%R11_LP), reg; \ rol $2*LP_SIZE+1, reg # define PTR_DEMANGLE(reg) ror $2*LP_SIZE+1, reg; \ - xor %fs:POINTER_GUARD, reg + mov __pointer_chk_guard@GOTPCREL(%rip), %R11_LP;\ + xor (%R11_LP), reg # else # include <stdbit.h> -# include <tls.h> +# include <stdint.h> +extern uintptr_t __pointer_chk_guard attribute_relro; # define PTR_MANGLE(var) \ do { \ (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \ + ^ __pointer_chk_guard); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) @@ -70,7 +72,7 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ (var) = (__typeof (var)) ((uintptr_t) (var) \ - ^ ((tcbhead_t __seg_fs *)0)->pointer_guard); \ + ^ __pointer_chk_guard); \ } while (0) # endif #endif diff --git a/sysdeps/x86_64/htl/tcb-offsets.sym b/sysdeps/x86_64/htl/tcb-offsets.sym index 7b7c719369..b36cfd6848 100644 --- a/sysdeps/x86_64/htl/tcb-offsets.sym +++ b/sysdeps/x86_64/htl/tcb-offsets.sym @@ -4,5 +4,4 @@ MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) SIGSTATE_OFFSET offsetof (tcbhead_t, _hurd_sigstate) diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym index 988a4b8593..aaa1dacd0c 100644 --- a/sysdeps/x86_64/nptl/tcb-offsets.sym +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym @@ -10,6 +10,5 @@ CLEANUP offsetof (struct pthread, cleanup) CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) -POINTER_GUARD offsetof (tcbhead_t, pointer_guard) FEATURE_1_OFFSET offsetof (tcbhead_t, feature_1) SSP_BASE_OFFSET offsetof (tcbhead_t, ssp_base) diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h index 836b2e2244..413ab074bf 100644 --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -49,7 +49,7 @@ typedef struct int gscope_flag; uintptr_t sysinfo; uintptr_t stack_guard; - uintptr_t pointer_guard; + uintptr_t __unused; unsigned long int unused_vgetcpu_cache[2]; /* Bit 0: X86_FEATURE_1_IBT. Bit 1: X86_FEATURE_1_SHSTK. @@ -186,14 +186,6 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80, = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) -/* Set the pointer guard field in the TCB head. */ -# define THREAD_SET_POINTER_GUARD(value) \ - THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) -# define THREAD_COPY_POINTER_GUARD(descr) \ - ((descr)->header.pointer_guard \ - = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) - - /* Get and set the global scope generation counter in the TCB head. */ # define THREAD_GSCOPE_FLAG_UNUSED 0 # define THREAD_GSCOPE_FLAG_USED 1 diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h index 77f13c986d..3d685e0f82 100644 --- a/sysdeps/x86_64/stackguard-macros.h +++ b/sysdeps/x86_64/stackguard-macros.h @@ -1,3 +1,11 @@ +#include <stdint.h> + #define STACK_CHK_GUARD (((tcbhead_t __seg_fs *)0)->stack_guard) -#define POINTER_CHK_GUARD (((tcbhead_t __seg_fs *)0)->pointer_guard) +#ifdef PTRGUARD_LOCAL +extern uintptr_t __pointer_chk_guard_local; +# define POINTER_CHK_GUARD __pointer_chk_guard_local +#else +extern uintptr_t __pointer_chk_guard; +# define POINTER_CHK_GUARD __pointer_chk_guard +#endif