diff --git a/glibc-rh1019452.patch b/glibc-rh1019452.patch new file mode 100644 index 0000000..cce6638 --- /dev/null +++ b/glibc-rh1019452.patch @@ -0,0 +1,216 @@ +commit b7f2d27dbd85f6a0966dc389ad4f8205085b7ae8 +Author: Will Newton +Date: Wed Aug 7 13:55:30 2013 +0100 + + ARM: Add pointer encryption support. + + Add support for pointer encryption in glibc internal structures in C + and assembler code. Pointer encryption is a glibc security feature + described here: + + https://sourceware.org/glibc/wiki/PointerEncryption + + The ARM implementation uses global variables instead of thread pointer + relative accesses to get the value of the pointer encryption guard + because accessing the thread pointer can be very expensive on older + ARM cores. + + ports/ChangeLog.arm: + + 2013-10-03 Will Newton + + * sysdeps/arm/__longjmp.S (__longjmp): Demangle fp, sp + and lr when restoring register values. + * sysdeps/arm/include/bits/setjmp.h (JMP_BUF_REGLIST): Remove + sp and lr from list and replace fp with a4. + * sysdeps/arm/jmpbuf-unwind.h (_jmpbuf_sp): New function. + (_JMPBUF_UNWINDS_ADJ): Call _jmpbuf_sp. + * sysdeps/arm/setjmp.S (__sigsetjmp): Mangle fp, sp and lr + before storing register values. + * sysdeps/arm/sysdep.h (LDST_GLOBAL): New macro. + * sysdeps/unix/sysv/linux/arm/sysdep.h (PTR_MANGLE): New macro. + (PTR_DEMANGLE): Likewise. (PTR_MANGLE2): Likewise. + (PTR_DEMANGLE2): Likewise. + +diff --git a/ports/sysdeps/arm/__longjmp.S b/ports/sysdeps/arm/__longjmp.S +index a5edede..2b1f7f4 100644 +--- a/ports/sysdeps/arm/__longjmp.S ++++ b/ports/sysdeps/arm/__longjmp.S +@@ -34,10 +34,24 @@ ENTRY (__longjmp) + sfi_breg ip, \ + ldr r4, [\B, #32] /* jmpbuf's sp */ + cfi_undefined (r4) ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (r4, r4, a3, a4) ++#endif + CHECK_SP (r4) + #endif + sfi_sp sfi_breg ip, \ + ldmia \B!, JMP_BUF_REGLIST ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (fp, a4, a3, a2) ++ ldr a4, [ip], #4 ++ PTR_DEMANGLE2 (sp, a4, a3) ++ ldr a4, [ip], #4 ++ PTR_DEMANGLE2 (lr, a4, a3) ++#else ++ mov fp, a4 ++ ldr sp, [ip], #4 ++ ldr lr, [ip], #4 ++#endif + cfi_restore (v1) + cfi_restore (v2) + cfi_restore (v3) +diff --git a/ports/sysdeps/arm/include/bits/setjmp.h b/ports/sysdeps/arm/include/bits/setjmp.h +index 1559d7b..64505dc 100644 +--- a/ports/sysdeps/arm/include/bits/setjmp.h ++++ b/ports/sysdeps/arm/include/bits/setjmp.h +@@ -26,8 +26,9 @@ + + #ifndef _ISOMAC + /* Register list for a ldm/stm instruction to load/store +- the general registers from a __jmp_buf. */ +-# define JMP_BUF_REGLIST {v1-v6, sl, fp, sp, lr} ++ the general registers from a __jmp_buf. The a4 register ++ contains fp at this point. */ ++# define JMP_BUF_REGLIST {a4, v1-v6, sl} + + /* Index of __jmp_buf where the sp register resides. */ + # define __JMP_BUF_SP 8 +diff --git a/ports/sysdeps/arm/jmpbuf-unwind.h b/ports/sysdeps/arm/jmpbuf-unwind.h +index 0863540..1b0d020 100644 +--- a/ports/sysdeps/arm/jmpbuf-unwind.h ++++ b/ports/sysdeps/arm/jmpbuf-unwind.h +@@ -17,6 +17,7 @@ + + #include + #include ++#include + #include + + /* Test if longjmp to JMPBUF would unwind the frame +@@ -27,8 +28,18 @@ + #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + ++static inline uintptr_t __attribute__ ((unused)) ++_jmpbuf_sp (__jmp_buf regs) ++{ ++ uintptr_t sp = regs[__JMP_BUF_SP]; ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (sp); ++#endif ++ return sp; ++} ++ + #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ +- ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[__JMP_BUF_SP] - (_adj)) ++ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + + /* We use the normal longjmp for unwinding. */ + #define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) +diff --git a/ports/sysdeps/arm/setjmp.S b/ports/sysdeps/arm/setjmp.S +index a6c161d..b38b919 100644 +--- a/ports/sysdeps/arm/setjmp.S ++++ b/ports/sysdeps/arm/setjmp.S +@@ -24,11 +24,25 @@ + #include + + ENTRY (__sigsetjmp) ++#ifdef PTR_MANGLE ++ PTR_MANGLE (a4, fp, a3, ip) ++#else ++ mov a4, fp ++#endif + mov ip, r0 + + /* Save registers */ + sfi_breg ip, \ + stmia \B!, JMP_BUF_REGLIST ++#ifdef PTR_MANGLE ++ PTR_MANGLE2 (a4, sp, a3) ++ str a4, [ip], #4 ++ PTR_MANGLE2 (a4, lr, a3) ++ str a4, [ip], #4 ++#else ++ str sp, [ip], #4 ++ str lr, [ip], #4 ++#endif + + #if !defined ARM_ASSUME_NO_IWMMXT || defined __SOFTFP__ + # define NEED_HWCAP 1 +diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h +index 5501597..3823617 100644 +--- a/ports/sysdeps/arm/sysdep.h ++++ b/ports/sysdeps/arm/sysdep.h +@@ -171,6 +171,18 @@ + 99: OP R, [pc, T] + # endif + ++/* Load or store to/from a global EXPR into/from R, using T. */ ++# define LDST_GLOBAL(OP, R, T, EXPR) \ ++ ldr T, 99f; \ ++ ldr R, 100f; \ ++98: add T, T, pc; \ ++ ldr T, [T, R]; \ ++ .subsection 2; \ ++99: .word _GLOBAL_OFFSET_TABLE_ - 98b - PC_OFS; \ ++100: .word EXPR##(GOT); \ ++ .previous; \ ++ OP R, [T] ++ + /* Cope with negative memory offsets, which thumb can't encode. + Use NEGOFF_ADJ_BASE to (conditionally) alter the base register, + and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm, +diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +index b195d8e..6cfe4e0 100644 +--- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h ++++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +@@ -435,8 +435,44 @@ __local_syscall_error: \ + + #endif /* __ASSEMBLER__ */ + +-/* Pointer mangling is not yet supported for ARM. */ +-#define PTR_MANGLE(var) (void) (var) +-#define PTR_DEMANGLE(var) (void) (var) ++/* Pointer mangling support. */ ++#if (defined NOT_IN_libc && defined IS_IN_rtld) || \ ++ (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread)) ++# ifdef __ASSEMBLER__ ++# define PTR_MANGLE(dst, src, guard, tmp) \ ++ LDST_PCREL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ ++ PTR_MANGLE2(dst, src, guard) ++/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ ++# define PTR_MANGLE2(dst, src, guard) \ ++ eor dst, src, guard ++# define PTR_DEMANGLE(dst, src, guard, tmp) \ ++ PTR_MANGLE (dst, src, guard, tmp) ++# define PTR_DEMANGLE2(dst, src, guard) \ ++ PTR_MANGLE2 (dst, src, 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) ++# define PTR_DEMANGLE(var) PTR_MANGLE (var) ++# endif ++#else ++# ifdef __ASSEMBLER__ ++# define PTR_MANGLE(dst, src, guard, tmp) \ ++ LDST_GLOBAL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard)); \ ++ PTR_MANGLE2(dst, src, guard) ++/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ ++# define PTR_MANGLE2(dst, src, guard) \ ++ eor dst, src, guard ++# define PTR_DEMANGLE(dst, src, guard, tmp) \ ++ PTR_MANGLE (dst, src, guard, tmp) ++# define PTR_DEMANGLE2(dst, src, guard) \ ++ PTR_MANGLE2 (dst, src, guard) ++# else ++extern uintptr_t __pointer_chk_guard attribute_relro; ++# define PTR_MANGLE(var) \ ++ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) ++# define PTR_DEMANGLE(var) PTR_MANGLE (var) ++# endif ++#endif + + #endif /* linux/arm/sysdep.h */ diff --git a/glibc.spec b/glibc.spec index c2464fe..a87a565 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.18 %define glibcversion 2.18 -%define glibcrelease 12%{?dist} +%define glibcrelease 13%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -191,6 +191,7 @@ Patch1001: %{name}-rh995841.patch Patch1002: %{name}-rh1008299.patch Patch1003: %{name}-rh1047979.patch Patch1004: %{name}-rh1055613.patch +Patch1005: %{name}-rh1019452.patch # # Patches submitted, but not yet approved upstream. @@ -568,6 +569,7 @@ package or when debugging this package. %patch0043 -p1 %patch1003 -p1 %patch1004 -p1 +%patch1005 -p1 ############################################################################## # %%prep - Additional prep required... @@ -1653,6 +1655,9 @@ rm -f *.filelist* %endif %changelog +* Thu Feb 6 2014 Siddhesh Poyarekar - 2.18-13 +- Add pointer mangling support for ARM (#1019452). + * Thu Jan 23 2014 Siddhesh Poyarekar - 2.18-12 - Use first name entry for address in /etc/hosts as the canonical name in getaddrinfo (#1047979).