[PATCH 2/8] Consolidate pointer guard to use a relro variable instead of the TCB

DJ Delorie dj@redhat.com
Wed Jun 10 03:03:37 GMT 2026


LGTM
Reviewed-by: DJ Delorie <dj@redhat.com>

Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
> diff --git a/sysdeps/i386/htl/tcb-offsets.sym b/sysdeps/i386/htl/tcb-offsets.sym
> index 7b7c7193695..b36cfd6848a 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)

Ok.

> diff --git a/sysdeps/i386/nptl/tcb-offsets.sym b/sysdeps/i386/nptl/tcb-offsets.sym
> index 2ec9e787c1f..48f79845129 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)

Ok.

> diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
> index 87dcf5dc1f4..fb8684230fb 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;

Ok.

> @@ -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))
> -
> -

Ok.

> diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h
> +#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

Ok.

> diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
>    int multiple_threads;
>    uintptr_t sysinfo;
>    uintptr_t stack_guard;
> -  uintptr_t pointer_guard;
> +  uintptr_t __unused;

Ok.

> @@ -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))
> -

Ok.

> diff --git a/sysdeps/mach/hurd/x86_64/tls.h b/sysdeps/mach/hurd/x86_64/tls.h
> index 85ea75b5b51..3543e9be347 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;

Ok.

> @@ -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))

Ok.

> diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym
>  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))

Ok.

> diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
>  /* 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.  */

Ok.

> @@ -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;

Ok.

> @@ -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())
> -

Ok.

> diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h
> -#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

Ok.

> diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h
>  #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

Ok.

> diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c
>  __longjmp (__jmp_buf env, int val)
>  {
>  #ifdef PTR_DEMANGLE
> -  uintptr_t guard = THREAD_GET_POINTER_GUARD ();
> +  uintptr_t guard = PTR_GUARD_VALUE;

Ok.

> diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
>    ((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)
> -

Ok.

> diff --git a/sysdeps/s390/stackguard-macros.h b/sysdeps/s390/stackguard-macros.h
>  #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

Ok.

> diff --git a/sysdeps/sh/nptl/tcb-offsets.sym b/sysdeps/sh/nptl/tcb-offsets.sym
>  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)

Ok.

> diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
>  typedef struct
>  {
>    dtv_t *dtv;
> -  uintptr_t pointer_guard;
> +  uintptr_t __unused;
>  } tcbhead_t;

Ok.

> @@ -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;})
> -

Ok.

> diff --git a/sysdeps/sh/stackguard-macros.h b/sysdeps/sh/stackguard-macros.h
>  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

Ok.

> diff --git a/sysdeps/sparc/nptl/tcb-offsets.sym b/sysdeps/sparc/nptl/tcb-offsets.sym
>  #include <tls.h>
>  
>  MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
> -POINTER_GUARD			offsetof (tcbhead_t, pointer_guard)

Ok.

> diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
>  #endif
>    uintptr_t sysinfo;
>    uintptr_t stack_guard;
> -  uintptr_t pointer_guard;
> +  uintptr_t __unused;

Ok.

> @@ -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 ())
> -

Ok.

> diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h
>  #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

Ok.

> diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h
>  #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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h
>  #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.  */

Ok.

>  # include <sysdeps/generic/pointer_guard.h>
>  #else
>  # ifdef __ASSEMBLER__
> +#  include <sysdep.h>
> +#  ifdef SHARED
> +/* The global guard is reached through the GOT.  setjmp/__longjmp save and
> +   restore %ebx and %esi around the mangling, so they can be used here as
> +   the GOT pointer and a scratch register.  */

Ok; at the moment this is only used for i386 setjmp/__longjmp (the
non-asm PTR_MANGLE is used many other places)

> -#  define PTR_MANGLE(reg)	xorl %gs:POINTER_GUARD, reg;		      \
> +#   define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
> +				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
> +				xorl (%esi), reg;			      \
>  				roll $9, reg

Ok.

> -#  define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
> -				xorl %gs:POINTER_GUARD, reg
> +#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
> +				LOAD_PIC_REG (bx);			      \
> +				movl __pointer_chk_guard@GOT(%ebx), %esi;     \
> +				xorl (%esi), reg

Ok.

> +#  elif defined PIC
> +/* Static PIE: the module-local guard is reached via @GOTOFF.  */
> +#   define PTR_MANGLE(reg)	LOAD_PIC_REG (bx);			      \
> +				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg; \
> +				roll $9, reg

Ok.

> +#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
> +				LOAD_PIC_REG (bx);			      \
> +				xorl __pointer_chk_guard_local@GOTOFF(%ebx), reg

Ok.

> +#  else
> +/* Position-dependent code addresses the guard directly.  */
> +#   define PTR_MANGLE(reg)	xorl __pointer_chk_guard_local, reg;	      \
> +				roll $9, reg
> +#   define PTR_DEMANGLE(reg)	rorl $9, reg;				      \
> +				xorl __pointer_chk_guard_local, reg
> +#  endif

Ok.

>  # 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)

ok.

> @@ -46,8 +73,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)

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h
> -/* 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__
> -#  if defined(__PPC64__) || defined(__powerpc64__)
> -#   define LOAD  ld
> -#   define TPREG r13
> +#  include <sysdep.h>
> +#  ifdef SHARED
> +#   define PTR_GUARD_SYM	__pointer_chk_guard
>  #  else
> -#   define LOAD  lwz
> -#   define TPREG r2
> +#   define PTR_GUARD_SYM	__pointer_chk_guard_local
>  #  endif
> +
> +#  if defined(__PPC64__) || defined(__powerpc64__)
> +#   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 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

Ok.

> -#  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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/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

Ok.

>  #  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)

Ok.

>  # 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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h
> -/* Pointer obfuscation implenentation.  Generic (no-op) version.
> +/* Pointer obfuscation implenentation.  SH version.

Ok.

> @@ -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

Ok.

> +#  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:

Ok.

> +#  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:

Ok.

>  #  define PTR_MANGLE(reg, tmp) \
> -     stc gbr,tmp; mov.l @(POINTER_GUARD,tmp),tmp; xor tmp,reg
> +     PTR_GUARD_LOAD (tmp); xor tmp,reg

Ok.

> -#  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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h
>  # 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; both are dead at every
> +   mangling site.  */
> +#   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

Ok.

>  #  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)

Ok.

>  # 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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h
>  # 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

Ok.

>  #  define PTR_MANGLE(dreg, reg, tmpreg) \
> -  ldx   [%g7 + POINTER_GUARD], tmpreg; \
> -  xor   reg, tmpreg, dreg
> +	PTR_GUARD_LOAD (tmpreg);					\
> +	xor	reg, tmpreg, dreg

Ok.

>  #  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

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h b/sysdeps/unix/sysv/linux/x86_64/pointer_guard.h
>  #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))))

Ok.

> @@ -51,17 +50,20 @@ extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
> -#  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

Ok.

>  #  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

Ok.

>  #  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

Ok.

> diff --git a/sysdeps/x86_64/htl/tcb-offsets.sym b/sysdeps/x86_64/htl/tcb-offsets.sym
>  
>  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)

Ok.

> diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym
> -POINTER_GUARD		offsetof (tcbhead_t, pointer_guard)

Ok.

> diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
>    int gscope_flag;
>    uintptr_t sysinfo;
>    uintptr_t stack_guard;
> -  uintptr_t pointer_guard;
> +  uintptr_t __unused;

Ok.

> @@ -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))
> -
> -

Ok.

> diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h
> index 77f13c986d8..3d685e0f828 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

Ok.



More information about the Libc-alpha mailing list