parent
730a16fa1d
commit
f4ab03df66
216
glibc-rh1019452.patch
Normal file
216
glibc-rh1019452.patch
Normal file
@ -0,0 +1,216 @@
|
||||
commit b7f2d27dbd85f6a0966dc389ad4f8205085b7ae8
|
||||
Author: Will Newton <will.newton@linaro.org>
|
||||
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 <will.newton@linaro.org>
|
||||
|
||||
* 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 <setjmp.h>
|
||||
#include <stdint.h>
|
||||
+#include <sysdep.h>
|
||||
#include <unwind.h>
|
||||
|
||||
/* 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 <arm-features.h>
|
||||
|
||||
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 */
|
@ -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 <siddhesh@redhat.com> - 2.18-13
|
||||
- Add pointer mangling support for ARM (#1019452).
|
||||
|
||||
* Thu Jan 23 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-12
|
||||
- Use first name entry for address in /etc/hosts as the canonical name
|
||||
in getaddrinfo (#1047979).
|
||||
|
Loading…
Reference in New Issue
Block a user