Compare commits

...

15 Commits
master ... f20

Author SHA1 Message Date
Siddhesh Poyarekar
0053a33360 CVE-2014-7817: wordexp fails to honour WRDE_NOCMD (#1167569). 2015-02-27 15:46:25 +05:30
Siddhesh Poyarekar
3d4581ecbb Crashes on invalid input in IBM gconv modules (CVE-2014-6040, #1135842) 2015-02-23 14:55:39 +05:30
Siddhesh Poyarekar
48e40fc12c Fix lll_unlock twice in pthread_cond_broadcast (#1104400) 2014-10-01 15:03:44 +05:30
Carlos O'Donell
a8f6d0e189 Resolves: #1146967.
- Disable lock elision support for Intel hardware until microcode
  updates can be done in early bootup (#1146967).
2014-09-26 11:56:48 -04:00
Siddhesh Poyarekar
d28e1906da Fix failing tst-setlocale3 (#rh1118581) 2014-08-26 20:38:56 +05:30
Siddhesh Poyarekar
7822f98805 Fix typo 2014-08-26 16:30:19 +05:30
Siddhesh Poyarekar
1aa86f5e9f Fix CVE-2014-5119 and CVE-2014-0475 2014-08-26 16:22:44 +05:30
Siddhesh Poyarekar
f4ab03df66 Resolves: #1019452
Add pointer mangling support for ARM.
2014-02-06 16:42:20 +05:30
Siddhesh Poyarekar
730a16fa1d Fix parsing of 0e+0 as float 2014-01-23 15:53:11 +05:30
Siddhesh Poyarekar
f40ae7b7fc Resolves: #1047979
Use first name entry for address in /etc/hosts as the canonical name
in getaddrinfo.
2014-01-23 15:49:14 +05:30
Carlos O'Donell
470c96d6ab Resolves: #1009145
- Allow ldconfig cached objects previously marked as hard or soft
  ABI to now become unmarked without raising an error. This works
  around a binutils bug that caused objects to become unmarked.
  (#1009145)
2013-10-02 21:37:43 -04:00
Siddhesh Poyarekar
00541bf6f3 - Fix check for PI mutex on non-x86 systems (#1007590). 2013-10-01 20:30:47 +05:30
Carlos O'Donell
f4ac86c2ae Resolves: #985625
- Fix CVE-2013-4788: Static applications now support pointer mangling.
  Existing static applications must be recompiled (#985625).
2013-09-23 01:55:38 -04:00
Patsy Franklin
fda0a1a26c Resolves: #804768
- Require specific binutils, or later, for s390/s390x support.
2013-09-18 14:36:07 -04:00
Siddhesh Poyarekar
349064e5e6 Fix integer overflows in *valloc and memalign (CVE-2013-4332, #1008299). 2013-09-16 15:29:03 +05:30
14 changed files with 3217 additions and 2 deletions

46
glibc-rh1007590.patch Normal file
View File

@ -0,0 +1,46 @@
commit ab8473b63982c814cdf509b8061fe0152cf3fd39
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Tue Oct 1 14:29:00 2013 +0530
Fix PI mutex check in pthread_cond_broadcast and pthread_cond_signal
The check had a typo - it checked for PTHREAD_MUTEX_ROBUST instead of
PTHREAD_MUTEX_NORMAL_ROBUST_NP. It has now been replaced by the
already existing convenience macro USE_REQUEUE_PI.
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
index 0702ec0..7ba9efa 100644
--- a/nptl/pthread_cond_broadcast.c
+++ b/nptl/pthread_cond_broadcast.c
@@ -63,10 +63,7 @@ __pthread_cond_broadcast (cond)
#if (defined lll_futex_cmp_requeue_pi \
&& defined __ASSUME_REQUEUE_PI)
- int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
- pi_flag &= mut->__data.__kind;
-
- if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP)
+ if (USE_REQUEUE_PI (mut))
{
if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX,
&mut->__data.__lock, futex_val,
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
index 102d0b3..ffc35dc 100644
--- a/nptl/pthread_cond_signal.c
+++ b/nptl/pthread_cond_signal.c
@@ -49,14 +49,9 @@ __pthread_cond_signal (cond)
#if (defined lll_futex_cmp_requeue_pi \
&& defined __ASSUME_REQUEUE_PI)
- int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP;
pthread_mutex_t *mut = cond->__data.__mutex;
- /* Do not use requeue for pshared condvars. */
- if (mut != (void *) ~0l)
- pi_flag &= mut->__data.__kind;
-
- if (__builtin_expect (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP, 0)
+ if (USE_REQUEUE_PI (mut)
/* This can only really fail with a ENOSYS, since nobody can modify
futex while we have the cond_lock. */
&& lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0,

46
glibc-rh1008299.patch Normal file
View File

@ -0,0 +1,46 @@
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 3148c5f..f7718a9 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3015,6 +3015,13 @@ __libc_memalign(size_t alignment, size_t bytes)
/* Otherwise, ensure that it is at least a minimum chunk size */
if (alignment < MINSIZE) alignment = MINSIZE;
+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - alignment - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
arena_get(ar_ptr, bytes + alignment + MINSIZE);
if(!ar_ptr)
return 0;
@@ -3046,6 +3046,13 @@ __libc_valloc(size_t bytes)
size_t pagesz = GLRO(dl_pagesize);
+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - pagesz - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
void *(*hook) (size_t, size_t, const void *) =
force_reg (__memalign_hook);
if (__builtin_expect (hook != NULL, 0))
@@ -3082,6 +3082,13 @@ __libc_pvalloc(size_t bytes)
size_t page_mask = GLRO(dl_pagesize) - 1;
size_t rounded_bytes = (bytes + page_mask) & ~(page_mask);
+ /* Check for overflow. */
+ if (bytes > SIZE_MAX - 2*pagesz - MINSIZE)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
void *(*hook) (size_t, size_t, const void *) =
force_reg (__memalign_hook);
if (__builtin_expect (hook != NULL, 0))

22
glibc-rh1009145.patch Normal file
View File

@ -0,0 +1,22 @@
#
# Will not go upstream. This is a Fedora local patch that is a workaround.
#
--- glibc-2.18-151-g303e567.orig/elf/ldconfig.c 2013-09-25 14:01:01.522446341 -0400
+++ glibc-2.18-151-g303e567/elf/ldconfig.c 2013-09-25 14:06:31.094218857 -0400
@@ -959,6 +959,16 @@
|| dlib_ptr->flag == FLAG_ELF_LIBC6)
&& flag == FLAG_ELF)
dlib_ptr->flag = flag;
+#ifdef __arm__
+ /* In Fedora 20 binutils regressed temporarily and failed to
+ mark hard ABI objects with the correct flag. Therefore we
+ must accept unmarked objects that were previously marked
+ hard ABI. We can remove this check once the entire distribution
+ has been rebuilt. */
+ else if (dlib_ptr->flag & FLAG_ARM_LIBHF &&
+ (flag == FLAG_ELF_LIBC6))
+ ;
+#endif
else
error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
dlib_ptr->name, direntry->d_name,

216
glibc-rh1019452.patch Normal file
View 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 */

555
glibc-rh1047979.patch Normal file
View File

@ -0,0 +1,555 @@
commit 5a4c6d53f50b264d60cf6453576ca2810c7890b7
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Thu Nov 28 17:18:12 2013 +0530
Get canonical name in getaddrinfo from hosts file for AF_INET (fixes 16077)
AF_INET lookup in hosts file uses _nss_files_gethostbyname2_r, which
is not capable of returning a canonical name if it has found one.
This change adds _nss_files_gethostbyname3_r, which wraps around
_nss_files_gethostbyname2_r and then returns result.h_name as the
canonical name.
diff --git a/nss/Versions b/nss/Versions
index d13d570..f8ababc 100644
--- a/nss/Versions
+++ b/nss/Versions
@@ -40,6 +40,7 @@ libnss_files {
_nss_files_endhostent;
_nss_files_gethostbyaddr_r;
_nss_files_gethostbyname2_r;
+ _nss_files_gethostbyname3_r;
_nss_files_gethostbyname4_r;
_nss_files_gethostbyname_r;
_nss_files_gethostent_r;
diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index 6db2535..957c9aa 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -97,262 +97,12 @@ LINE_PARSER
STRING_FIELD (result->h_name, isspace, 1);
})
-
-
-#define HOST_DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
-enum nss_status \
-_nss_files_get##name##_r (proto, \
- struct STRUCTURE *result, char *buffer, \
- size_t buflen, int *errnop H_ERRNO_PROTO) \
-{ \
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data); \
- buffer += pad; \
- buflen = buflen > pad ? buflen - pad : 0; \
- \
- __libc_lock_lock (lock); \
- \
- /* Reset file pointer to beginning or open file. */ \
- enum nss_status status = internal_setent (keep_stream); \
- \
- if (status == NSS_STATUS_SUCCESS) \
- { \
- /* Tell getent function that we have repositioned the file pointer. */ \
- last_use = getby; \
- \
- while ((status = internal_getent (result, buffer, buflen, errnop \
- H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
- == NSS_STATUS_SUCCESS) \
- { break_if_match } \
- \
- if (status == NSS_STATUS_SUCCESS \
- && _res_hconf.flags & HCONF_FLAG_MULTI) \
- { \
- /* We have to get all host entries from the file. */ \
- size_t tmp_buflen = MIN (buflen, 4096); \
- char tmp_buffer_stack[tmp_buflen] \
- __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\
- char *tmp_buffer = tmp_buffer_stack; \
- struct hostent tmp_result_buf; \
- int naddrs = 1; \
- int naliases = 0; \
- char *bufferend; \
- bool tmp_buffer_malloced = false; \
- \
- while (result->h_aliases[naliases] != NULL) \
- ++naliases; \
- \
- bufferend = (char *) &result->h_aliases[naliases + 1]; \
- \
- again: \
- while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \
- tmp_buflen, errnop H_ERRNO_ARG \
- EXTRA_ARGS_VALUE)) \
- == NSS_STATUS_SUCCESS) \
- { \
- int matches = 1; \
- struct hostent *old_result = result; \
- result = &tmp_result_buf; \
- /* The following piece is a bit clumsy but we want to use the \
- `break_if_match' value. The optimizer should do its \
- job. */ \
- do \
- { \
- break_if_match \
- result = old_result; \
- } \
- while ((matches = 0)); \
- \
- if (matches) \
- { \
- /* We could be very clever and try to recycle a few bytes \
- in the buffer instead of generating new arrays. But \
- we are not doing this here since it's more work than \
- it's worth. Simply let the user provide a bit bigger \
- buffer. */ \
- char **new_h_addr_list; \
- char **new_h_aliases; \
- int newaliases = 0; \
- size_t newstrlen = 0; \
- int cnt; \
- \
- /* Count the new aliases and the length of the strings. */ \
- while (tmp_result_buf.h_aliases[newaliases] != NULL) \
- { \
- char *cp = tmp_result_buf.h_aliases[newaliases]; \
- ++newaliases; \
- newstrlen += strlen (cp) + 1; \
- } \
- /* If the real name is different add it also to the \
- aliases. This means that there is a duplication \
- in the alias list but this is really the user's \
- problem. */ \
- if (strcmp (old_result->h_name, \
- tmp_result_buf.h_name) != 0) \
- { \
- ++newaliases; \
- newstrlen += strlen (tmp_result_buf.h_name) + 1; \
- } \
- \
- /* Make sure bufferend is aligned. */ \
- assert ((bufferend - (char *) 0) % sizeof (char *) == 0); \
- \
- /* Now we can check whether the buffer is large enough. \
- 16 is the maximal size of the IP address. */ \
- if (bufferend + 16 + (naddrs + 2) * sizeof (char *) \
- + roundup (newstrlen, sizeof (char *)) \
- + (naliases + newaliases + 1) * sizeof (char *) \
- >= buffer + buflen) \
- { \
- *errnop = ERANGE; \
- *herrnop = NETDB_INTERNAL; \
- status = NSS_STATUS_TRYAGAIN; \
- goto out; \
- } \
- \
- new_h_addr_list = \
- (char **) (bufferend \
- + roundup (newstrlen, sizeof (char *)) \
- + 16); \
- new_h_aliases = \
- (char **) ((char *) new_h_addr_list \
- + (naddrs + 2) * sizeof (char *)); \
- \
- /* Copy the old data in the new arrays. */ \
- for (cnt = 0; cnt < naddrs; ++cnt) \
- new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; \
- \
- for (cnt = 0; cnt < naliases; ++cnt) \
- new_h_aliases[cnt] = old_result->h_aliases[cnt]; \
- \
- /* Store the new strings. */ \
- cnt = 0; \
- while (tmp_result_buf.h_aliases[cnt] != NULL) \
- { \
- new_h_aliases[naliases++] = bufferend; \
- bufferend = (__stpcpy (bufferend, \
- tmp_result_buf.h_aliases[cnt]) \
- + 1); \
- ++cnt; \
- } \
- \
- if (cnt < newaliases) \
- { \
- new_h_aliases[naliases++] = bufferend; \
- bufferend = __stpcpy (bufferend, \
- tmp_result_buf.h_name) + 1; \
- } \
- \
- /* Final NULL pointer. */ \
- new_h_aliases[naliases] = NULL; \
- \
- /* Round up the buffer end address. */ \
- bufferend += (sizeof (char *) \
- - ((bufferend - (char *) 0) \
- % sizeof (char *))) % sizeof (char *); \
- \
- /* Now the new address. */ \
- new_h_addr_list[naddrs++] = \
- memcpy (bufferend, tmp_result_buf.h_addr, \
- tmp_result_buf.h_length); \
- \
- /* Also here a final NULL pointer. */ \
- new_h_addr_list[naddrs] = NULL; \
- \
- /* Store the new array pointers. */ \
- old_result->h_aliases = new_h_aliases; \
- old_result->h_addr_list = new_h_addr_list; \
- \
- /* Compute the new buffer end. */ \
- bufferend = (char *) &new_h_aliases[naliases + 1]; \
- assert (bufferend <= buffer + buflen); \
- \
- result = old_result; \
- } \
- } \
- \
- if (status == NSS_STATUS_TRYAGAIN) \
- { \
- size_t newsize = 2 * tmp_buflen; \
- if (tmp_buffer_malloced) \
- { \
- char *newp = realloc (tmp_buffer, newsize); \
- if (newp != NULL) \
- { \
- assert ((((uintptr_t) newp) \
- & (__alignof__ (struct hostent_data) - 1)) \
- == 0); \
- tmp_buffer = newp; \
- tmp_buflen = newsize; \
- goto again; \
- } \
- } \
- else if (!__libc_use_alloca (buflen + newsize)) \
- { \
- tmp_buffer = malloc (newsize); \
- if (tmp_buffer != NULL) \
- { \
- assert ((((uintptr_t) tmp_buffer) \
- & (__alignof__ (struct hostent_data) - 1)) \
- == 0); \
- tmp_buffer_malloced = true; \
- tmp_buflen = newsize; \
- goto again; \
- } \
- } \
- else \
- { \
- tmp_buffer \
- = extend_alloca (tmp_buffer, tmp_buflen, \
- newsize \
- + __alignof__ (struct hostent_data)); \
- tmp_buffer = (char *) (((uintptr_t) tmp_buffer \
- + __alignof__ (struct hostent_data) \
- - 1) \
- & ~(__alignof__ (struct hostent_data)\
- - 1)); \
- goto again; \
- } \
- } \
- else \
- status = NSS_STATUS_SUCCESS; \
- out: \
- if (tmp_buffer_malloced) \
- free (tmp_buffer); \
- } \
- \
- \
- if (! keep_stream) \
- internal_endent (); \
- } \
- \
- __libc_lock_unlock (lock); \
- \
- return status; \
-}
-
-
#define EXTRA_ARGS_VALUE \
, ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
#include "files-XXX.c"
-HOST_DB_LOOKUP (hostbyname, ,,
- {
- LOOKUP_NAME_CASE (h_name, h_aliases)
- }, const char *name)
#undef EXTRA_ARGS_VALUE
-
-/* XXX Is using _res to determine whether we want to convert IPv4 addresses
- to IPv6 addresses really the right thing to do? */
-#define EXTRA_ARGS_VALUE \
- , af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
-HOST_DB_LOOKUP (hostbyname2, ,,
- {
- LOOKUP_NAME_CASE (h_name, h_aliases)
- }, const char *name, int af)
-#undef EXTRA_ARGS_VALUE
-
-
/* We only need to consider IPv4 mapped addresses if the input to the
gethostbyaddr() function is an IPv6 address. */
#define EXTRA_ARGS_VALUE \
@@ -365,6 +115,263 @@ DB_LOOKUP (hostbyaddr, ,,,
}, const void *addr, socklen_t len, int af)
#undef EXTRA_ARGS_VALUE
+enum nss_status
+_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop, int32_t *ttlp, char **canonp)
+{
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
+ buffer += pad;
+ buflen = buflen > pad ? buflen - pad : 0;
+
+ __libc_lock_lock (lock);
+
+ /* Reset file pointer to beginning or open file. */
+ enum nss_status status = internal_setent (keep_stream);
+
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ /* XXX Is using _res to determine whether we want to convert IPv4
+ addresses to IPv6 addresses really the right thing to do? */
+ int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0);
+
+ /* Tell getent function that we have repositioned the file pointer. */
+ last_use = getby;
+
+ while ((status = internal_getent (result, buffer, buflen, errnop,
+ herrnop, af, flags))
+ == NSS_STATUS_SUCCESS)
+ {
+ LOOKUP_NAME_CASE (h_name, h_aliases)
+ }
+
+ if (status == NSS_STATUS_SUCCESS
+ && _res_hconf.flags & HCONF_FLAG_MULTI)
+ {
+ /* We have to get all host entries from the file. */
+ size_t tmp_buflen = MIN (buflen, 4096);
+ char tmp_buffer_stack[tmp_buflen]
+ __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));
+ char *tmp_buffer = tmp_buffer_stack;
+ struct hostent tmp_result_buf;
+ int naddrs = 1;
+ int naliases = 0;
+ char *bufferend;
+ bool tmp_buffer_malloced = false;
+
+ while (result->h_aliases[naliases] != NULL)
+ ++naliases;
+
+ bufferend = (char *) &result->h_aliases[naliases + 1];
+
+ again:
+ while ((status = internal_getent (&tmp_result_buf, tmp_buffer,
+ tmp_buflen, errnop, herrnop, af,
+ flags))
+ == NSS_STATUS_SUCCESS)
+ {
+ int matches = 1;
+ struct hostent *old_result = result;
+ result = &tmp_result_buf;
+ /* The following piece is a bit clumsy but we want to use the
+ `LOOKUP_NAME_CASE' value. The optimizer should do its
+ job. */
+ do
+ {
+ LOOKUP_NAME_CASE (h_name, h_aliases)
+ result = old_result;
+ }
+ while ((matches = 0));
+
+ if (matches)
+ {
+ /* We could be very clever and try to recycle a few bytes
+ in the buffer instead of generating new arrays. But
+ we are not doing this here since it's more work than
+ it's worth. Simply let the user provide a bit bigger
+ buffer. */
+ char **new_h_addr_list;
+ char **new_h_aliases;
+ int newaliases = 0;
+ size_t newstrlen = 0;
+ int cnt;
+
+ /* Count the new aliases and the length of the strings. */
+ while (tmp_result_buf.h_aliases[newaliases] != NULL)
+ {
+ char *cp = tmp_result_buf.h_aliases[newaliases];
+ ++newaliases;
+ newstrlen += strlen (cp) + 1;
+ }
+ /* If the real name is different add it also to the
+ aliases. This means that there is a duplication
+ in the alias list but this is really the user's
+ problem. */
+ if (strcmp (old_result->h_name,
+ tmp_result_buf.h_name) != 0)
+ {
+ ++newaliases;
+ newstrlen += strlen (tmp_result_buf.h_name) + 1;
+ }
+
+ /* Make sure bufferend is aligned. */
+ assert ((bufferend - (char *) 0) % sizeof (char *) == 0);
+
+ /* Now we can check whether the buffer is large enough.
+ 16 is the maximal size of the IP address. */
+ if (bufferend + 16 + (naddrs + 2) * sizeof (char *)
+ + roundup (newstrlen, sizeof (char *))
+ + (naliases + newaliases + 1) * sizeof (char *)
+ >= buffer + buflen)
+ {
+ *errnop = ERANGE;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ goto out;
+ }
+
+ new_h_addr_list =
+ (char **) (bufferend
+ + roundup (newstrlen, sizeof (char *))
+ + 16);
+ new_h_aliases =
+ (char **) ((char *) new_h_addr_list
+ + (naddrs + 2) * sizeof (char *));
+
+ /* Copy the old data in the new arrays. */
+ for (cnt = 0; cnt < naddrs; ++cnt)
+ new_h_addr_list[cnt] = old_result->h_addr_list[cnt];
+
+ for (cnt = 0; cnt < naliases; ++cnt)
+ new_h_aliases[cnt] = old_result->h_aliases[cnt];
+
+ /* Store the new strings. */
+ cnt = 0;
+ while (tmp_result_buf.h_aliases[cnt] != NULL)
+ {
+ new_h_aliases[naliases++] = bufferend;
+ bufferend = (__stpcpy (bufferend,
+ tmp_result_buf.h_aliases[cnt])
+ + 1);
+ ++cnt;
+ }
+
+ if (cnt < newaliases)
+ {
+ new_h_aliases[naliases++] = bufferend;
+ bufferend = __stpcpy (bufferend,
+ tmp_result_buf.h_name) + 1;
+ }
+
+ /* Final NULL pointer. */
+ new_h_aliases[naliases] = NULL;
+
+ /* Round up the buffer end address. */
+ bufferend += (sizeof (char *)
+ - ((bufferend - (char *) 0)
+ % sizeof (char *))) % sizeof (char *);
+
+ /* Now the new address. */
+ new_h_addr_list[naddrs++] =
+ memcpy (bufferend, tmp_result_buf.h_addr,
+ tmp_result_buf.h_length);
+
+ /* Also here a final NULL pointer. */
+ new_h_addr_list[naddrs] = NULL;
+
+ /* Store the new array pointers. */
+ old_result->h_aliases = new_h_aliases;
+ old_result->h_addr_list = new_h_addr_list;
+
+ /* Compute the new buffer end. */
+ bufferend = (char *) &new_h_aliases[naliases + 1];
+ assert (bufferend <= buffer + buflen);
+
+ result = old_result;
+ }
+ }
+
+ if (status == NSS_STATUS_TRYAGAIN)
+ {
+ size_t newsize = 2 * tmp_buflen;
+ if (tmp_buffer_malloced)
+ {
+ char *newp = realloc (tmp_buffer, newsize);
+ if (newp != NULL)
+ {
+ assert ((((uintptr_t) newp)
+ & (__alignof__ (struct hostent_data) - 1))
+ == 0);
+ tmp_buffer = newp;
+ tmp_buflen = newsize;
+ goto again;
+ }
+ }
+ else if (!__libc_use_alloca (buflen + newsize))
+ {
+ tmp_buffer = malloc (newsize);
+ if (tmp_buffer != NULL)
+ {
+ assert ((((uintptr_t) tmp_buffer)
+ & (__alignof__ (struct hostent_data) - 1))
+ == 0);
+ tmp_buffer_malloced = true;
+ tmp_buflen = newsize;
+ goto again;
+ }
+ }
+ else
+ {
+ tmp_buffer
+ = extend_alloca (tmp_buffer, tmp_buflen,
+ newsize
+ + __alignof__ (struct hostent_data));
+ tmp_buffer = (char *) (((uintptr_t) tmp_buffer
+ + __alignof__ (struct hostent_data)
+ - 1)
+ & ~(__alignof__ (struct hostent_data)
+ - 1));
+ goto again;
+ }
+ }
+ else
+ status = NSS_STATUS_SUCCESS;
+ out:
+ if (tmp_buffer_malloced)
+ free (tmp_buffer);
+ }
+
+ if (! keep_stream)
+ internal_endent ();
+ }
+
+ if (canonp && status == NSS_STATUS_SUCCESS)
+ *canonp = result->h_name;
+
+ __libc_lock_unlock (lock);
+
+ return status;
+}
+
+enum nss_status
+_nss_files_gethostbyname_r (const char *name, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop)
+{
+ int af = ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET);
+
+ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+ errnop, herrnop, NULL, NULL);
+}
+
+enum nss_status
+_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result,
+ char *buffer, size_t buflen, int *errnop,
+ int *herrnop)
+{
+ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
+ errnop, herrnop, NULL, NULL);
+}
enum nss_status
_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,

70
glibc-rh1055613.patch Normal file
View File

@ -0,0 +1,70 @@
commit a4966c6104918ac884ee1131a4ed23c5ad6b4c5a
Author: Andreas Schwab <schwab@suse.de>
Date: Thu Oct 31 12:51:03 2013 +0100
Fix parsing of 0e+0 as float
diff --git a/stdio-common/tst-sscanf.c b/stdio-common/tst-sscanf.c
index 1edb227..3c34f58 100644
--- a/stdio-common/tst-sscanf.c
+++ b/stdio-common/tst-sscanf.c
@@ -109,6 +109,19 @@ struct test double_tests[] =
{ L("-inf"), L("%g"), 1 }
};
+struct test2
+{
+ const CHAR *str;
+ const CHAR *fmt;
+ int retval;
+ char residual;
+} double_tests2[] =
+{
+ { L("0e+0"), L("%g%c"), 1, 0 },
+ { L("0xe+0"), L("%g%c"), 2, '+' },
+ { L("0x.e+0"), L("%g%c"), 2, '+' },
+};
+
int
main (void)
{
@@ -196,5 +209,26 @@ main (void)
}
}
+ for (i = 0; i < sizeof (double_tests2) / sizeof (double_tests2[0]); ++i)
+ {
+ double dummy;
+ int ret;
+ char c = 0;
+
+ if ((ret = SSCANF (double_tests2[i].str, double_tests2[i].fmt,
+ &dummy, &c)) != double_tests2[i].retval)
+ {
+ printf ("double_tests2[%d] returned %d != %d\n",
+ i, ret, double_tests2[i].retval);
+ result = 1;
+ }
+ else if (ret == 2 && c != double_tests2[i].residual)
+ {
+ printf ("double_tests2[%d] stopped at '%c' != '%c'\n",
+ i, c, double_tests2[i].residual);
+ result = 1;
+ }
+ }
+
return result;
}
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index 78dc2fc..e6fa8f3 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -1966,6 +1966,8 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
if (width > 0)
--width;
}
+ else
+ got_digit = 1;
}
while (1)

26
glibc-rh1104400.patch Normal file
View File

@ -0,0 +1,26 @@
commit 8f630cca5c36941db1cb48726016bbed80ec1041
Author: Yang Yingliang <yangyingliang@huawei.com>
Date: Wed Apr 30 15:46:18 2014 +0530
Fix lll_unlock twice in pthread_cond_broadcast
lll_unlock() will be called again if it goes to "wake_all" in
pthread_cond_broadcast(). This may make another thread which is
waiting for lock in pthread_cond_timedwait() unlock. So there are
more than one threads get the lock, it will break the shared data.
It's introduced by commit 8313cb997d2d("FUTEX_*_REQUEUE_PI support for
non-x86 code")
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
index ed30e7c..7c6c9ea 100644
--- a/nptl/pthread_cond_broadcast.c
+++ b/nptl/pthread_cond_broadcast.c
@@ -81,6 +81,7 @@ __pthread_cond_broadcast (cond)
wake_all:
lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
+ return 0;
}
/* We are done. */

476
glibc-rh1118581-2.patch Normal file
View File

@ -0,0 +1,476 @@
commit 2bf1804182cc4bd671193587c8d5e3de45a9618e
Author: Joseph Myers <joseph@codesourcery.com>
Date: Wed Jun 4 23:37:25 2014 +0000
Include LOCPATH in default test environment.
Tests run using the default $(make-test-out) automatically get
GCONV_PATH and LC_ALL set, whether or not those environment variables
are actually needed for the individual test. However, they do not get
LOCPATH set, meaning that a large number of tests have -ENV settings
just to set LOCPATH.
This patch moves LOCPATH into the default environment used for all
tests, on the principle that like GCONV_PATH any settings needed to
use files associated with the newly built library, rather than any old
installed files, are appropriate to use by default.
A further motivation is that various tests using .sh files also set
some combination of LC_ALL, GCONV_PATH and LOCPATH. Preferably .sh
files should also use the default environment with any additions
required for the individual test. Now, it was suggested in
<https://sourceware.org/ml/libc-alpha/2014-05/msg00715.html> that
various Makefile variables used in testing should be derived by
composing the -before-env and -after-env variables used when explicit
environment settings are required. With such a change, it's also
natural for those variables to include the default settings (via some
intermediate makefile variable also used in make-test-out).
Because some .sh files only set variables that correspond to the
default settings, or a subset thereof, and this applies to more of the
.sh files once LOCPATH is in the default settings, doing so reduces
the size of a revised version of
<https://sourceware.org/ml/libc-alpha/2014-05/msg00596.html>: scripts
only needing the (expanded) default settings will not need to receive
the separate -before-env and -after-env variables, only the single
variable they do at present. So moving LOCPATH into the default
settings can reduce churn caused by subsequent patches.
Tested x86_64 and x86.
* Rules (make-test-out): Include
LOCPATH=$(common-objpfx)localedata in default environment.
* debug/Makefile (tst-chk1-ENV): Remove variable.
(tst-chk2-ENV): Likewise.
(tst-chk3-ENV): Likewise.
(tst-chk4-ENV): Likewise.
(tst-chk5-ENV): Likewise.
(tst-chk6-ENV): Likewise.
(tst-lfschk1-ENV): Likewise.
(tst-lfschk2-ENV): Likewise.
(tst-lfschk3-ENV): Likewise.
(tst-lfschk4-ENV): Likewise.
(tst-lfschk5-ENV): Likewise.
(tst-lfschk6-ENV): Likewise.
* iconvdata/Makefile (bug-iconv6-ENV): Likewise.
(tst-iconv7-ENV): Likewise.
* intl/Makefile (LOCPATH-ENV): Likewise.
(tst-codeset-ENV): Likewise.
(tst-gettext3-ENV): Likewise.
(tst-gettext5-ENV): Likewise.
* libio/Makefile (tst-widetext-ENV): Don't set LOCPATH.
(tst-fopenloc-ENV): Likewise.
(tst-fgetws-ENV): Remove variable.
(tst-ungetwc1-ENV): Likewise.
(tst-ungetwc2-ENV): Likewise.
(bug-ungetwc2-ENV): Likewise.
(tst-swscanf-ENV): Likewise.
(bug-ftell-ENV): Likewise.
(tst-fgetwc-ENV): Likewise.
(tst-fseek-ENV): Likewise.
(tst-ftell-partial-wide-ENV): Likewise.
(tst-ftell-active-handler-ENV): Likewise.
(tst-ftell-append-ENV): Likewise.
* posix/Makefile (tst-fnmatch-ENV): Likewise.
(tst-regexloc-ENV): Likewise.
(bug-regex1-ENV): Likewise.
(tst-regex-ENV): Likewise.
(tst-regex2-ENV): Likewise.
(bug-regex5-ENV): Likewise.
(bug-regex6-ENV): Likewise.
(bug-regex17-ENV): Likewise.
(bug-regex18-ENV): Likewise.
(bug-regex19-ENV): Likewise.
(bug-regex20-ENV): Likewise.
(bug-regex22-ENV): Likewise.
(bug-regex23-ENV): Likewise.
(bug-regex25-ENV): Likewise.
(bug-regex26-ENV): Likewise.
(bug-regex30-ENV): Likewise.
(bug-regex32-ENV): Likewise.
(bug-regex33-ENV): Likewise.
(bug-regex34-ENV): Likewise.
(bug-regex35-ENV): Likewise.
(tst-rxspencer-ENV): Likewise.
(tst-rxspencer-no-utf8-ENV): Likewise.
* stdio-common/Makefile (tst-sprintf-ENV): Likewise.
(tst-sscanf-ENV): Likewise.
(tst-swprintf-ENV): Likewise.
(tst-swscanf-ENV): Likewise.
(test-vfprintf-ENV): Likewise.
(scanf13-ENV): Likewise.
(bug14-ENV): Likewise.
(tst-grouping-ENV): Likewise.
* stdlib/Makefile (tst-strtod-ENV): Likewise.
(tst-strtod3-ENV): Likewise.
(tst-strtod4-ENV): Likewise.
(tst-strtod5-ENV): Likewise.
(testmb2-ENV): Likewise./
* string/Makefile (tst-strxfrm-ENV): Likewise.
(tst-strxfrm2-ENV): Likewise.
(bug-strcoll1-ENV): Likewise.
(test-strcasecmp-ENV): Likewise.
(test-strncasecmp-ENV): Likewise.
* time/Makefile (tst-strptime-ENV): Likewise.
(tst-ftime_l-ENV): Likewise.
* wcsmbs/Makefile (tst-btowc-ENV): Likewise.
(tst-mbrtowc-ENV): Likewise.
(tst-wcrtomb-ENV): Likewise.
(tst-mbrtowc2-ENV): Likewise.
(tst-c16c32-1-ENV): Likewise.
(tst-mbsnrtowcs-ENV): Likewise.
localedata/ChangeLog:
* Makefile (TEST_MBWC_ENV): Remove variable.
(tst_iswalnum-ENV): Likewise.
(tst_iswalpha-ENV): Likewise.
(tst_iswcntrl-ENV): Likewise.
(tst_iswctype-ENV): Likewise.
(tst_iswdigit-ENV): Likewise.
(tst_iswgraph-ENV): Likewise.
(tst_iswlower-ENV): Likewise.
(tst_iswprint-ENV): Likewise.
(tst_iswpunct-ENV): Likewise.
(tst_iswspace-ENV): Likewise.
(tst_iswupper-ENV): Likewise.
(tst_iswxdigit-ENV): Likewise.
(tst_mblen-ENV): Likewise.
(tst_mbrlen-ENV): Likewise.
(tst_mbrtowc-ENV): Likewise.
(tst_mbsrtowcs-ENV): Likewise.
(tst_mbstowcs-ENV): Likewise.
(tst_mbtowc-ENV): Likewise.
(tst_strcoll-ENV): Likewise.
(tst_strfmon-ENV): Likewise.
(tst_strxfrm-ENV): Likewise.
(tst_swscanf-ENV): Likewise.
(tst_towctrans-ENV): Likewise.
(tst_towlower-ENV): Likewise.
(tst_towupper-ENV): Likewise.
(tst_wcrtomb-ENV): Likewise.
(tst_wcscat-ENV): Likewise.
(tst_wcschr-ENV): Likewise.
(tst_wcscmp-ENV): Likewise.
(tst_wcscoll-ENV): Likewise.
(tst_wcscpy-ENV): Likewise.
(tst_wcscspn-ENV): Likewise.
(tst_wcslen-ENV): Likewise.
(tst_wcsncat-ENV): Likewise.
(tst_wcsncmp-ENV): Likewise.
(tst_wcsncpy-ENV): Likewise.
(tst_wcspbrk-ENV): Likewise.
(tst_wcsrtombs-ENV): Likewise.
(tst_wcsspn-ENV): Likewise.
(tst_wcsstr-ENV): Likewise.
(tst_wcstod-ENV): Likewise.
(tst_wcstok-ENV): Likewise.
(tst_wcstombs-ENV): Likewise.
(tst_wcswidth-ENV): Likewise.
(tst_wcsxfrm-ENV): Likewise.
(tst_wctob-ENV): Likewise.
(tst_wctomb-ENV): Likewise.
(tst_wctrans-ENV): Likewise.
(tst_wctype-ENV): Likewise.
(tst_wcwidth-ENV): Likewise.
(tst-digits-ENV): Likewise.
(tst-mbswcs6-ENV): Likewise.
(tst-xlocale1-ENV): Likewise.
(tst-xlocale2-ENV): Likewise.
(tst-strfmon1-ENV): Likewise.
(tst-strptime-ENV): Likewise.
(tst-setlocale-ENV): Don't set LOCPATH.
(bug-iconv-trans-ENV): Remove variable.
(tst-sscanf-ENV): Likewise.
(tst-leaks-ENV): Don't set LOCPATH.
(bug-setlocale1-ENV): Remove variable.
(bug-setlocale1-static-ENV): Likewise.
(tst-setlocale2-ENV): Likewise.
diff --git a/Rules b/Rules
index feb304d..9f1a445 100644
--- a/Rules
+++ b/Rules
@@ -191,7 +191,8 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
# from the test programs and whatever input files are present.
make-test-out = $(test-wrapper-env) \
- GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
+ GCONV_PATH=$(common-objpfx)iconvdata \
+ LOCPATH=$(common-objpfx)localedata LC_ALL=C \
$($*-ENV) $(host-test-program-cmd) $($*-ARGS)
$(objpfx)%.out: %.input $(objpfx)%
$(make-test-out) > $@ < $(word 1,$^)
diff --git a/debug/Makefile b/debug/Makefile
index b599a22..c284c51 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -109,18 +109,6 @@ CFLAGS-tst-lfschk3.c = -Wno-format
CFLAGS-tst-lfschk4.cc = -Wno-format
CFLAGS-tst-lfschk5.cc = -Wno-format
CFLAGS-tst-lfschk6.cc = -Wno-format
-tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata
-tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata
-tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata
-tst-chk4-ENV = LOCPATH=$(common-objpfx)localedata
-tst-chk5-ENV = LOCPATH=$(common-objpfx)localedata
-tst-chk6-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk4-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk5-ENV = LOCPATH=$(common-objpfx)localedata
-tst-lfschk6-ENV = LOCPATH=$(common-objpfx)localedata
LDLIBS-tst-chk4 = -lstdc++
LDLIBS-tst-chk5 = -lstdc++
LDLIBS-tst-chk6 = -lstdc++
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 074d330..d98b6bd 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -73,9 +73,6 @@ tests += bug-iconv3
endif
test-srcs := tst-table-from tst-table-to
-
-bug-iconv6-ENV = LOCPATH=$(common-objpfx)localedata
-tst-iconv7-ENV = LOCPATH=$(common-objpfx)localedata
endif
# No code here is in libc.so.
diff --git a/intl/Makefile b/intl/Makefile
index f11449d..10051f6 100644
--- a/intl/Makefile
+++ b/intl/Makefile
@@ -118,11 +118,6 @@ CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\"
-LOCPATH-ENV = LOCPATH=$(common-objpfx)localedata
-tst-codeset-ENV = $(LOCPATH-ENV)
-tst-gettext3-ENV = $(LOCPATH-ENV)
-tst-gettext5-ENV = $(LOCPATH-ENV)
-
ifeq ($(have-thread-library),yes)
ifeq (yes,$(build-shared))
$(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
diff --git a/libio/Makefile b/libio/Makefile
index b324ccc..4552360 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -148,17 +148,8 @@ CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\"
tst_wprintf2-ARGS = "Some Text"
-tst-widetext-ENV = LOCPATH=$(common-objpfx)localedata LANGUAGE=C
-tst-fopenloc-ENV = LOCPATH=$(common-objpfx)localedata \
- MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
-tst-fgetws-ENV = LOCPATH=$(common-objpfx)localedata
-tst-ungetwc1-ENV = LOCPATH=$(common-objpfx)localedata
-tst-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
-bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
-tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata
-bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata
-tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata
-tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata
+tst-widetext-ENV = LANGUAGE=C
+tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
generated = tst-fopenloc.mtrace tst-fopenloc.check
diff --git a/localedata/Makefile b/localedata/Makefile
index d7ab445..20da00c 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -236,81 +236,14 @@ $(INSTALL-SUPPORTED-LOCALES): install-locales-dir
$(addprefix --prefix=,$(install_root)) $$locale; \
echo ' done'; \
-# The mbwc-tests need some environment setup to find the locale data files
-TEST_MBWC_ENV:= LOCPATH=$(common-objpfx)localedata
-tst_iswalnum-ENV = $(TEST_MBWC_ENV)
-tst_iswalpha-ENV = $(TEST_MBWC_ENV)
-tst_iswcntrl-ENV = $(TEST_MBWC_ENV)
-tst_iswctype-ENV = $(TEST_MBWC_ENV)
-tst_iswdigit-ENV = $(TEST_MBWC_ENV)
-tst_iswgraph-ENV = $(TEST_MBWC_ENV)
-tst_iswlower-ENV = $(TEST_MBWC_ENV)
-tst_iswprint-ENV = $(TEST_MBWC_ENV)
-tst_iswpunct-ENV = $(TEST_MBWC_ENV)
-tst_iswspace-ENV = $(TEST_MBWC_ENV)
-tst_iswupper-ENV = $(TEST_MBWC_ENV)
-tst_iswxdigit-ENV = $(TEST_MBWC_ENV)
-tst_mblen-ENV = $(TEST_MBWC_ENV)
-tst_mbrlen-ENV = $(TEST_MBWC_ENV)
-tst_mbrtowc-ENV = $(TEST_MBWC_ENV)
-tst_mbsrtowcs-ENV = $(TEST_MBWC_ENV)
-tst_mbstowcs-ENV = $(TEST_MBWC_ENV)
-tst_mbtowc-ENV = $(TEST_MBWC_ENV)
-tst_strcoll-ENV = $(TEST_MBWC_ENV)
-tst_strfmon-ENV = $(TEST_MBWC_ENV)
-tst_strxfrm-ENV = $(TEST_MBWC_ENV)
-tst_swscanf-ENV = $(TEST_MBWC_ENV)
-tst_towctrans-ENV = $(TEST_MBWC_ENV)
-tst_towlower-ENV = $(TEST_MBWC_ENV)
-tst_towupper-ENV = $(TEST_MBWC_ENV)
-tst_wcrtomb-ENV = $(TEST_MBWC_ENV)
-tst_wcscat-ENV = $(TEST_MBWC_ENV)
-tst_wcschr-ENV = $(TEST_MBWC_ENV)
-tst_wcscmp-ENV = $(TEST_MBWC_ENV)
-tst_wcscoll-ENV = $(TEST_MBWC_ENV)
-tst_wcscpy-ENV = $(TEST_MBWC_ENV)
-tst_wcscspn-ENV = $(TEST_MBWC_ENV)
-tst_wcslen-ENV = $(TEST_MBWC_ENV)
-tst_wcsncat-ENV = $(TEST_MBWC_ENV)
-tst_wcsncmp-ENV = $(TEST_MBWC_ENV)
-tst_wcsncpy-ENV = $(TEST_MBWC_ENV)
-tst_wcspbrk-ENV = $(TEST_MBWC_ENV)
-tst_wcsrtombs-ENV = $(TEST_MBWC_ENV)
-tst_wcsspn-ENV = $(TEST_MBWC_ENV)
-tst_wcsstr-ENV = $(TEST_MBWC_ENV)
-tst_wcstod-ENV = $(TEST_MBWC_ENV)
-tst_wcstok-ENV = $(TEST_MBWC_ENV)
-tst_wcstombs-ENV = $(TEST_MBWC_ENV)
-tst_wcswidth-ENV = $(TEST_MBWC_ENV)
-tst_wcsxfrm-ENV = $(TEST_MBWC_ENV)
-tst_wctob-ENV = $(TEST_MBWC_ENV)
-tst_wctomb-ENV = $(TEST_MBWC_ENV)
-tst_wctrans-ENV = $(TEST_MBWC_ENV)
-tst_wctype-ENV = $(TEST_MBWC_ENV)
-tst_wcwidth-ENV = $(TEST_MBWC_ENV)
-tst-digits-ENV = $(TEST_MBWC_ENV)
-tst-mbswcs6-ENV = $(TEST_MBWC_ENV)
-tst-xlocale1-ENV = $(TEST_MBWC_ENV)
-tst-xlocale2-ENV = $(TEST_MBWC_ENV)
-tst-strfmon1-ENV = $(TEST_MBWC_ENV)
-tst-strptime-ENV = $(TEST_MBWC_ENV)
-
-tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP
-
-bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata
-
-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
-
-tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \
- LOCPATH=$(common-objpfx)localedata
+tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP
+
+tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace
$(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@
-bug-setlocale1-ENV = LOCPATH=$(common-objpfx)localedata
bug-setlocale1-ARGS = -- $(host-test-program-cmd)
-bug-setlocale1-static-ENV = $(bug-setlocale1-ENV)
bug-setlocale1-static-ARGS = $(bug-setlocale1-ARGS)
-tst-setlocale2-ENV = LOCPATH=$(common-objpfx)localedata
$(objdir)/iconvdata/gconv-modules:
$(MAKE) -C ../iconvdata subdir=iconvdata $@
diff --git a/posix/Makefile b/posix/Makefile
index 328c2c5..3d75971 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -203,28 +203,7 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir);
tst-chmod-ARGS = $(objdir)
tst-vfork3-ARGS = --test-dir=$(objpfx)
-tst-fnmatch-ENV = LOCPATH=$(common-objpfx)localedata
-tst-regexloc-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex1-ENV = LOCPATH=$(common-objpfx)localedata
-tst-regex-ENV = LOCPATH=$(common-objpfx)localedata
-tst-regex2-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex5-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex6-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex17-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex18-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex19-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex20-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex22-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex23-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex25-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex26-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex30-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex32-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex33-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex34-ENV = LOCPATH=$(common-objpfx)localedata
-bug-regex35-ENV = LOCPATH=$(common-objpfx)localedata
tst-rxspencer-ARGS = --utf8 rxspencer/tests
-tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata
tst-pcre-ARGS = PCRE.tests
tst-boost-ARGS = BOOST.tests
bug-glob1-ARGS = "$(objpfx)"
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index f179eab..5f8e534 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -118,13 +118,6 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \
# We know the test has a format string problem.
CFLAGS-tst-sprintf.c = -Wno-format
-tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata
-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata
-tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata
-test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata
-scanf13-ENV = LOCPATH=$(common-objpfx)localedata
-bug14-ENV = LOCPATH=$(common-objpfx)localedata
-tst-grouping-ENV = LOCPATH=$(common-objpfx)localedata
CPPFLAGS += $(libio-mtsafe)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index d7a562f..0fdf7cc 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -123,11 +123,6 @@ include ../Rules
# Testdir has to be named stdlib and needs to be writable
test-canon-ARGS = --test-dir=${common-objpfx}stdlib
-tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata
-tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata
-tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata
-tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata
-testmb2-ENV = LOCPATH=$(common-objpfx)localedata
bug-fmtmsg1-ENV = SEV_LEVEL=foo,11,newsev
# Run a test on the header files we use.
diff --git a/string/Makefile b/string/Makefile
index 5a76872..70b9c19 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -67,9 +67,6 @@ include ../Rules
tester-ENV = LANGUAGE=C
inl-tester-ENV = LANGUAGE=C
noinl-tester-ENV = LANGUAGE=C
-tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata
-tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata
-bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata
CFLAGS-inl-tester.c = -fno-builtin
CFLAGS-noinl-tester.c = -fno-builtin
CFLAGS-tst-strlen.c = -fno-builtin
diff --git a/time/Makefile b/time/Makefile
index b7f3dba..a07c041 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -55,7 +55,4 @@ CFLAGS-test_time.c = -Wno-format
tst-getdate-ENV= DATEMSK=datemsk TZDIR=${common-objpfx}timezone/testdata
test_time-ARGS= EST5EDT CST
-tst-strptime-ENV = LOCPATH=${common-objpfx}localedata
-tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata
-
bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 197ca7d..42843a6 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -80,10 +80,3 @@ CPPFLAGS += $(libio-mtsafe)
# We need to find the default version of strtold_l in stdlib.
CPPFLAGS-wcstold_l.c = -I../stdlib
-
-tst-btowc-ENV = LOCPATH=$(common-objpfx)localedata
-tst-mbrtowc-ENV = LOCPATH=$(common-objpfx)localedata
-tst-wcrtomb-ENV = LOCPATH=$(common-objpfx)localedata
-tst-mbrtowc2-ENV = LOCPATH=$(common-objpfx)localedata
-tst-c16c32-1-ENV = LOCPATH=$(common-objpfx)localedata
-tst-mbsnrtowcs-ENV = LOCPATH=$(common-objpfx)localedata

631
glibc-rh1118581.patch Normal file
View File

@ -0,0 +1,631 @@
commit 585367266923156ac6fb789939a923641ba5aaf4
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed May 28 14:05:03 2014 +0200
manual: Update the locale documentation
commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon May 12 15:24:12 2014 +0200
_nl_find_locale: Improve handling of crafted locale names [BZ #17137]
Prevent directory traversal in locale-related environment variables
(CVE-2014-0475).
commit d183645616b0533b3acee28f1a95570bffbdf50f
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed May 28 14:41:52 2014 +0200
setlocale: Use the heap for the copy of the locale argument
This avoids alloca calls with potentially large arguments.
diff -pruN glibc-2.18/locale/findlocale.c glibc-2.18.patched/locale/findlocale.c
--- glibc-2.18/locale/findlocale.c 2013-08-11 04:22:55.000000000 +0530
+++ glibc-2.18.patched/locale/findlocale.c 2014-08-26 16:14:50.403253778 +0530
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <assert.h>
+#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
@@ -57,6 +58,45 @@ struct loaded_l10nfile *_nl_locale_file_
const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR;
+/* Checks if the name is actually present, that is, not NULL and not
+ empty. */
+static inline int
+name_present (const char *name)
+{
+ return name != NULL && name[0] != '\0';
+}
+
+/* Checks that the locale name neither extremely long, nor contains a
+ ".." path component (to prevent directory traversal). */
+static inline int
+valid_locale_name (const char *name)
+{
+ /* Not set. */
+ size_t namelen = strlen (name);
+ /* Name too long. The limit is arbitrary and prevents stack overflow
+ issues later. */
+ if (__glibc_unlikely (namelen > 255))
+ return 0;
+ /* Directory traversal attempt. */
+ static const char slashdot[4] = {'/', '.', '.', '/'};
+ if (__glibc_unlikely (memmem (name, namelen,
+ slashdot, sizeof (slashdot)) != NULL))
+ return 0;
+ if (namelen == 2 && __glibc_unlikely (name[0] == '.' && name [1] == '.'))
+ return 0;
+ if (namelen >= 3
+ && __glibc_unlikely (((name[0] == '.'
+ && name[1] == '.'
+ && name[2] == '/')
+ || (name[namelen - 3] == '/'
+ && name[namelen - 2] == '.'
+ && name[namelen - 1] == '.'))))
+ return 0;
+ /* If there is a slash in the name, it must start with one. */
+ if (__glibc_unlikely (memchr (name, '/', namelen) != NULL) && name[0] != '/')
+ return 0;
+ return 1;
+}
struct __locale_data *
internal_function
@@ -65,7 +105,7 @@ _nl_find_locale (const char *locale_path
{
int mask;
/* Name of the locale for this category. */
- char *loc_name;
+ char *loc_name = (char *) *name;
const char *language;
const char *modifier;
const char *territory;
@@ -73,31 +113,39 @@ _nl_find_locale (const char *locale_path
const char *normalized_codeset;
struct loaded_l10nfile *locale_file;
- if ((*name)[0] == '\0')
+ if (loc_name[0] == '\0')
{
/* The user decides which locale to use by setting environment
variables. */
- *name = getenv ("LC_ALL");
- if (*name == NULL || (*name)[0] == '\0')
- *name = getenv (_nl_category_names.str
+ loc_name = getenv ("LC_ALL");
+ if (!name_present (loc_name))
+ loc_name = getenv (_nl_category_names.str
+ _nl_category_name_idxs[category]);
- if (*name == NULL || (*name)[0] == '\0')
- *name = getenv ("LANG");
+ if (!name_present (loc_name))
+ loc_name = getenv ("LANG");
+ if (!name_present (loc_name))
+ loc_name = (char *) _nl_C_name;
}
- if (*name == NULL || (*name)[0] == '\0'
- || (__builtin_expect (__libc_enable_secure, 0)
- && strchr (*name, '/') != NULL))
- *name = (char *) _nl_C_name;
+ /* We used to fall back to the C locale if the name contains a slash
+ character '/', but we now check for directory traversal in
+ valid_locale_name, so this is no longer necessary. */
- if (__builtin_expect (strcmp (*name, _nl_C_name), 1) == 0
- || __builtin_expect (strcmp (*name, _nl_POSIX_name), 1) == 0)
+ if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0
+ || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0)
{
/* We need not load anything. The needed data is contained in
the library itself. */
*name = (char *) _nl_C_name;
return _nl_C[category];
}
+ else if (!valid_locale_name (loc_name))
+ {
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
+ *name = loc_name;
/* We really have to load some data. First we try the archive,
but only if there was no LOCPATH environment variable specified. */
diff -pruN glibc-2.18/locale/setlocale.c glibc-2.18.patched/locale/setlocale.c
--- glibc-2.18/locale/setlocale.c 2013-08-11 04:22:55.000000000 +0530
+++ glibc-2.18.patched/locale/setlocale.c 2014-08-26 16:14:50.401253764 +0530
@@ -272,6 +272,8 @@ setlocale (int category, const char *loc
of entries of the form `CATEGORY=VALUE'. */
const char *newnames[__LC_LAST];
struct __locale_data *newdata[__LC_LAST];
+ /* Copy of the locale argument, for in-place splitting. */
+ char *locale_copy = NULL;
/* Set all name pointers to the argument name. */
for (category = 0; category < __LC_LAST; ++category)
@@ -281,7 +283,13 @@ setlocale (int category, const char *loc
if (__builtin_expect (strchr (locale, ';') != NULL, 0))
{
/* This is a composite name. Make a copy and split it up. */
- char *np = strdupa (locale);
+ locale_copy = strdup (locale);
+ if (__glibc_unlikely (locale_copy == NULL))
+ {
+ __libc_rwlock_unlock (__libc_setlocale_lock);
+ return NULL;
+ }
+ char *np = locale_copy;
char *cp;
int cnt;
@@ -299,6 +307,7 @@ setlocale (int category, const char *loc
{
error_return:
__libc_rwlock_unlock (__libc_setlocale_lock);
+ free (locale_copy);
/* Bogus category name. */
ERROR_RETURN;
@@ -391,8 +400,9 @@ setlocale (int category, const char *loc
/* Critical section left. */
__libc_rwlock_unlock (__libc_setlocale_lock);
- /* Free the resources (the locale path variable). */
+ /* Free the resources. */
free (locale_path);
+ free (locale_copy);
return composite;
}
diff -pruN glibc-2.18/localedata/Makefile glibc-2.18.patched/localedata/Makefile
--- glibc-2.18/localedata/Makefile 2014-08-26 16:15:22.656474571 +0530
+++ glibc-2.18.patched/localedata/Makefile 2014-08-26 16:14:50.403253778 +0530
@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_is
tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2
+ tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3
tests-static = bug-setlocale1-static
tests += $(tests-static)
ifeq (yes,$(build-shared))
diff -pruN glibc-2.18/localedata/tst-setlocale3.c glibc-2.18.patched/localedata/tst-setlocale3.c
--- glibc-2.18/localedata/tst-setlocale3.c 1970-01-01 05:30:00.000000000 +0530
+++ glibc-2.18.patched/localedata/tst-setlocale3.c 2014-08-26 16:14:50.403253778 +0530
@@ -0,0 +1,203 @@
+/* Regression test for setlocale invalid environment variable handling.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* The result of setlocale may be overwritten by subsequent calls, so
+ this wrapper makes a copy. */
+static char *
+setlocale_copy (int category, const char *locale)
+{
+ const char *result = setlocale (category, locale);
+ if (result == NULL)
+ return NULL;
+ return strdup (result);
+}
+
+static char *de_locale;
+
+static void
+setlocale_fail (const char *envstring)
+{
+ setenv ("LC_CTYPE", envstring, 1);
+ if (setlocale (LC_CTYPE, "") != NULL)
+ {
+ printf ("unexpected setlocale success for \"%s\" locale\n", envstring);
+ exit (1);
+ }
+ const char *newloc = setlocale (LC_CTYPE, NULL);
+ if (strcmp (newloc, de_locale) != 0)
+ {
+ printf ("failed setlocale call \"%s\" changed locale to \"%s\"\n",
+ envstring, newloc);
+ exit (1);
+ }
+}
+
+static void
+setlocale_success (const char *envstring)
+{
+ setenv ("LC_CTYPE", envstring, 1);
+ char *newloc = setlocale_copy (LC_CTYPE, "");
+ if (newloc == NULL)
+ {
+ printf ("setlocale for \"%s\": %m\n", envstring);
+ exit (1);
+ }
+ if (strcmp (newloc, de_locale) == 0)
+ {
+ printf ("setlocale with LC_CTYPE=\"%s\" left locale at \"%s\"\n",
+ envstring, de_locale);
+ exit (1);
+ }
+ if (setlocale (LC_CTYPE, de_locale) == NULL)
+ {
+ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+ de_locale, envstring);
+ exit (1);
+ }
+ char *newloc2 = setlocale_copy (LC_CTYPE, newloc);
+ if (newloc2 == NULL)
+ {
+ printf ("restoring locale \"%s\" following \"%s\": %m\n",
+ newloc, envstring);
+ exit (1);
+ }
+ if (strcmp (newloc, newloc2) != 0)
+ {
+ printf ("representation of locale \"%s\" changed from \"%s\" to \"%s\"",
+ envstring, newloc, newloc2);
+ exit (1);
+ }
+ free (newloc);
+ free (newloc2);
+
+ if (setlocale (LC_CTYPE, de_locale) == NULL)
+ {
+ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+ de_locale, envstring);
+ exit (1);
+ }
+}
+
+/* Checks that a known-good locale still works if LC_ALL contains a
+ value which should be ignored. */
+static void
+setlocale_ignore (const char *to_ignore)
+{
+ const char *fr_locale = "fr_FR.UTF-8";
+ setenv ("LC_CTYPE", fr_locale, 1);
+ char *expected_locale = setlocale_copy (LC_CTYPE, "");
+ if (expected_locale == NULL)
+ {
+ printf ("setlocale with LC_CTYPE=\"%s\" failed: %m\n", fr_locale);
+ exit (1);
+ }
+ if (setlocale (LC_CTYPE, de_locale) == NULL)
+ {
+ printf ("failed to restore locale: %m\n");
+ exit (1);
+ }
+ unsetenv ("LC_CTYPE");
+
+ setenv ("LC_ALL", to_ignore, 1);
+ setenv ("LC_CTYPE", fr_locale, 1);
+ const char *actual_locale = setlocale (LC_CTYPE, "");
+ if (actual_locale == NULL)
+ {
+ printf ("setlocale with LC_ALL, LC_CTYPE=\"%s\" failed: %m\n",
+ fr_locale);
+ exit (1);
+ }
+ if (strcmp (actual_locale, expected_locale) != 0)
+ {
+ printf ("setlocale under LC_ALL failed: got \"%s\", expected \"%s\"\n",
+ actual_locale, expected_locale);
+ exit (1);
+ }
+ unsetenv ("LC_CTYPE");
+ setlocale_success (fr_locale);
+ unsetenv ("LC_ALL");
+ free (expected_locale);
+}
+
+static int
+do_test (void)
+{
+ /* The glibc test harness sets this environment variable
+ uncondionally. */
+ unsetenv ("LC_ALL");
+
+ de_locale = setlocale_copy (LC_CTYPE, "de_DE.UTF-8");
+ if (de_locale == NULL)
+ {
+ printf ("setlocale (LC_CTYPE, \"de_DE.UTF-8\"): %m\n");
+ return 1;
+ }
+ setlocale_success ("C");
+ setlocale_success ("en_US.UTF-8");
+ setlocale_success ("/en_US.UTF-8");
+ setlocale_success ("//en_US.UTF-8");
+ setlocale_ignore ("");
+
+ setlocale_fail ("does-not-exist");
+ setlocale_fail ("/");
+ setlocale_fail ("/../localedata/en_US.UTF-8");
+ setlocale_fail ("en_US.UTF-8/");
+ setlocale_fail ("en_US.UTF-8/..");
+ setlocale_fail ("en_US.UTF-8/../en_US.UTF-8");
+ setlocale_fail ("../localedata/en_US.UTF-8");
+ {
+ size_t large_length = 1024;
+ char *large_name = malloc (large_length + 1);
+ if (large_name == NULL)
+ {
+ puts ("malloc failure");
+ return 1;
+ }
+ memset (large_name, '/', large_length);
+ const char *suffix = "en_US.UTF-8";
+ strcpy (large_name + large_length - strlen (suffix), suffix);
+ setlocale_fail (large_name);
+ free (large_name);
+ }
+ {
+ size_t huge_length = 64 * 1024 * 1024;
+ char *huge_name = malloc (huge_length + 1);
+ if (huge_name == NULL)
+ {
+ puts ("malloc failure");
+ return 1;
+ }
+ memset (huge_name, 'X', huge_length);
+ huge_name[huge_length] = '\0';
+ /* Construct a composite locale specification. */
+ const char *prefix = "LC_CTYPE=de_DE.UTF-8;LC_TIME=";
+ memcpy (huge_name, prefix, strlen (prefix));
+ setlocale_fail (huge_name);
+ free (huge_name);
+ }
+
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff -pruN glibc-2.18/manual/locale.texi glibc-2.18.patched/manual/locale.texi
--- glibc-2.18/manual/locale.texi 2013-08-11 04:22:55.000000000 +0530
+++ glibc-2.18.patched/manual/locale.texi 2014-08-26 16:14:50.404253785 +0530
@@ -29,6 +29,7 @@ will follow the conventions preferred by
* Setting the Locale:: How a program specifies the locale
with library functions.
* Standard Locales:: Locale names available on all systems.
+* Locale Names:: Format of system-specific locale names.
* Locale Information:: How to access the information for the locale.
* Formatting Numbers:: A dedicated function to format numbers.
* Yes-or-No Questions:: Check a Response against the locale.
@@ -99,14 +100,16 @@ locale named @samp{espana-castellano} to
most of Spain.
The set of locales supported depends on the operating system you are
-using, and so do their names. We can't make any promises about what
-locales will exist, except for one standard locale called @samp{C} or
-@samp{POSIX}. Later we will describe how to construct locales.
-@comment (@pxref{Building Locale Files}).
+using, and so do their names, except that the standard locale called
+@samp{C} or @samp{POSIX} always exist. @xref{Locale Names}.
+
+In order to force the system to always use the default locale, the
+user can set the @code{LC_ALL} environment variable to @samp{C}.
@cindex combining locales
-A user also has the option of specifying different locales for different
-purposes---in effect, choosing a mixture of multiple locales.
+A user also has the option of specifying different locales for
+different purposes---in effect, choosing a mixture of multiple
+locales. @xref{Locale Categories}.
For example, the user might specify the locale @samp{espana-castellano}
for most purposes, but specify the locale @samp{usa-english} for
@@ -120,7 +123,7 @@ which locales apply. However, the user
for a particular subset of those purposes.
@node Locale Categories, Setting the Locale, Choosing Locale, Locales
-@section Categories of Activities that Locales Affect
+@section Locale Categories
@cindex categories for locales
@cindex locale categories
@@ -128,7 +131,11 @@ The purposes that locales serve are grou
that a user or a program can choose the locale for each category
independently. Here is a table of categories; each name is both an
environment variable that a user can set, and a macro name that you can
-use as an argument to @code{setlocale}.
+use as the first argument to @code{setlocale}.
+
+The contents of the environment variable (or the string in the second
+argument to @code{setlocale}) has to be a valid locale name.
+@xref{Locale Names}.
@vtable @code
@comment locale.h
@@ -172,7 +179,7 @@ for affirmative and negative responses.
@comment locale.h
@comment ISO
@item LC_ALL
-This is not an environment variable; it is only a macro that you can use
+This is not a category; it is only a macro that you can use
with @code{setlocale} to set a single locale for all purposes. Setting
this environment variable overwrites all selections by the other
@code{LC_*} variables or @code{LANG}.
@@ -225,13 +232,7 @@ The symbols in this section are defined
@comment ISO
@deftypefun {char *} setlocale (int @var{category}, const char *@var{locale})
The function @code{setlocale} sets the current locale for category
-@var{category} to @var{locale}. A list of all the locales the system
-provides can be created by running
-
-@pindex locale
-@smallexample
- locale -a
-@end smallexample
+@var{category} to @var{locale}.
If @var{category} is @code{LC_ALL}, this specifies the locale for all
purposes. The other possible values of @var{category} specify an
@@ -256,10 +257,9 @@ is passed in as @var{locale} parameter.
When you read the current locale for category @code{LC_ALL}, the value
encodes the entire combination of selected locales for all categories.
-In this case, the value is not just a single locale name. In fact, we
-don't make any promises about what it looks like. But if you specify
-the same ``locale name'' with @code{LC_ALL} in a subsequent call to
-@code{setlocale}, it restores the same combination of locale selections.
+If you specify the same ``locale name'' with @code{LC_ALL} in a
+subsequent call to @code{setlocale}, it restores the same combination
+of locale selections.
To be sure you can use the returned string encoding the currently selected
locale at a later time, you must make a copy of the string. It is not
@@ -275,20 +275,15 @@ for @var{category}.
If a nonempty string is given for @var{locale}, then the locale of that
name is used if possible.
+The effective locale name (either the second argument to
+@code{setlocale}, or if the argument is an empty string, the name
+obtained from the process environment) must be valid locale name.
+@xref{Locale Names}.
+
If you specify an invalid locale name, @code{setlocale} returns a null
pointer and leaves the current locale unchanged.
@end deftypefun
-The path used for finding locale data can be set using the
-@code{LOCPATH} environment variable. The default path for finding
-locale data is system specific. It is computed from the value given
-as the prefix while configuring the C library. This value normally is
-@file{/usr} or @file{/}. For the former the complete path is:
-
-@smallexample
-/usr/lib/locale
-@end smallexample
-
Here is an example showing how you might use @code{setlocale} to
temporarily switch to a new locale.
@@ -328,7 +323,7 @@ locale categories, and future versions o
portability, assume that any symbol beginning with @samp{LC_} might be
defined in @file{locale.h}.
-@node Standard Locales, Locale Information, Setting the Locale, Locales
+@node Standard Locales, Locale Names, Setting the Locale, Locales
@section Standard Locales
The only locale names you can count on finding on all operating systems
@@ -362,7 +357,94 @@ with the environment, rather than trying
locale explicitly by name. Remember, different machines might have
different sets of locales installed.
-@node Locale Information, Formatting Numbers, Standard Locales, Locales
+@node Locale Names, Locale Information, Standard Locales, Locales
+@section Locale Names
+
+The following command prints a list of locales supported by the
+system:
+
+@pindex locale
+@smallexample
+ locale -a
+@end smallexample
+
+@strong{Portability Note:} With the notable exception of the standard
+locale names @samp{C} and @samp{POSIX}, locale names are
+system-specific.
+
+Most locale names follow XPG syntax and consist of up to four parts:
+
+@smallexample
+@var{language}[_@var{territory}[.@var{codeset}]][@@@var{modifier}]
+@end smallexample
+
+Beside the first part, all of them are allowed to be missing. If the
+full specified locale is not found, less specific ones are looked for.
+The various parts will be stripped off, in the following order:
+
+@enumerate
+@item
+codeset
+@item
+normalized codeset
+@item
+territory
+@item
+modifier
+@end enumerate
+
+For example, the locale name @samp{de_AT.iso885915@@euro} denotes a
+German-language locale for use in Austria, using the ISO-8859-15
+(Latin-9) character set, and with the Euro as the currency symbol.
+
+In addition to locale names which follow XPG syntax, systems may
+provide aliases such as @samp{german}. Both categories of names must
+not contain the slash character @samp{/}.
+
+If the locale name starts with a slash @samp{/}, it is treated as a
+path relative to the configured locale directories; see @code{LOCPATH}
+below. The specified path must not contain a component @samp{..}, or
+the name is invalid, and @code{setlocale} will fail.
+
+@strong{Portability Note:} POSIX suggests that if a locale name starts
+with a slash @samp{/}, it is resolved as an absolute path. However,
+@theglibc{} treats it as a relative path under the directories listed
+in @code{LOCPATH} (or the default locale directory if @code{LOCPATH}
+is unset).
+
+Locale names which are longer than an implementation-defined limit are
+invalid and cause @code{setlocale} to fail.
+
+As a special case, locale names used with @code{LC_ALL} can combine
+several locales, reflecting different locale settings for different
+categories. For example, you might want to use a U.S. locale with ISO
+A4 paper format, so you set @code{LANG} to @samp{en_US.UTF-8}, and
+@code{LC_PAPER} to @samp{de_DE.UTF-8}. In this case, the
+@code{LC_ALL}-style combined locale name is
+
+@smallexample
+LC_CTYPE=en_US.UTF-8;LC_TIME=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;@dots{}
+@end smallexample
+
+followed by other category settings not shown here.
+
+@vindex LOCPATH
+The path used for finding locale data can be set using the
+@code{LOCPATH} environment variable. This variable lists the
+directories in which to search for locale definitions, separated by a
+colon @samp{:}.
+
+The default path for finding locale data is system specific. A typical
+value for the @code{LOCPATH} default is:
+
+@smallexample
+/usr/share/locale
+@end smallexample
+
+The value of @code{LOCPATH} is ignored by privileged programs for
+security reasons, and only the default directory is used.
+
+@node Locale Information, Formatting Numbers, Locale Names, Locales
@section Accessing Locale Information
There are several ways to access locale information. The simplest

199
glibc-rh1119128.patch Normal file
View File

@ -0,0 +1,199 @@
2014-08-21 Florian Weimer <fweimer@redhat.com>
[BZ #17187]
* iconv/gconv_trans.c (struct known_trans, search_tree, lock,
trans_compare, open_translit, __gconv_translit_find):
Remove module loading code.
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
index 1e25854..d71c029 100644
--- a/iconv/gconv_trans.c
+++ b/iconv/gconv_trans.c
@@ -238,181 +238,11 @@ __gconv_transliterate (struct __gconv_step *step,
return __GCONV_ILLEGAL_INPUT;
}
-
-/* Structure to represent results of found (or not) transliteration
- modules. */
-struct known_trans
-{
- /* This structure must remain the first member. */
- struct trans_struct info;
-
- char *fname;
- void *handle;
- int open_count;
-};
-
-
-/* Tree with results of previous calls to __gconv_translit_find. */
-static void *search_tree;
-
-/* We modify global data. */
-__libc_lock_define_initialized (static, lock);
-
-
-/* Compare two transliteration entries. */
-static int
-trans_compare (const void *p1, const void *p2)
-{
- const struct known_trans *s1 = (const struct known_trans *) p1;
- const struct known_trans *s2 = (const struct known_trans *) p2;
-
- return strcmp (s1->info.name, s2->info.name);
-}
-
-
-/* Open (maybe reopen) the module named in the struct. Get the function
- and data structure pointers we need. */
-static int
-open_translit (struct known_trans *trans)
-{
- __gconv_trans_query_fct queryfct;
-
- trans->handle = __libc_dlopen (trans->fname);
- if (trans->handle == NULL)
- /* Not available. */
- return 1;
-
- /* Find the required symbol. */
- queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");
- if (queryfct == NULL)
- {
- /* We cannot live with that. */
- close_and_out:
- __libc_dlclose (trans->handle);
- trans->handle = NULL;
- return 1;
- }
-
- /* Get the context. */
- if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)
- != 0)
- goto close_and_out;
-
- /* Of course we also have to have the actual function. */
- trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");
- if (trans->info.trans_fct == NULL)
- goto close_and_out;
-
- /* Now the optional functions. */
- trans->info.trans_init_fct =
- __libc_dlsym (trans->handle, "gconv_trans_init");
- trans->info.trans_context_fct =
- __libc_dlsym (trans->handle, "gconv_trans_context");
- trans->info.trans_end_fct =
- __libc_dlsym (trans->handle, "gconv_trans_end");
-
- trans->open_count = 1;
-
- return 0;
-}
-
-
int
internal_function
__gconv_translit_find (struct trans_struct *trans)
{
- struct known_trans **found;
- const struct path_elem *runp;
- int res = 1;
-
- /* We have to have a name. */
- assert (trans->name != NULL);
-
- /* Acquire the lock. */
- __libc_lock_lock (lock);
-
- /* See whether we know this module already. */
- found = __tfind (trans, &search_tree, trans_compare);
- if (found != NULL)
- {
- /* Is this module available? */
- if ((*found)->handle != NULL)
- {
- /* Maybe we have to reopen the file. */
- if ((*found)->handle != (void *) -1)
- /* The object is not unloaded. */
- res = 0;
- else if (open_translit (*found) == 0)
- {
- /* Copy the data. */
- *trans = (*found)->info;
- (*found)->open_count++;
- res = 0;
- }
- }
- }
- else
- {
- size_t name_len = strlen (trans->name) + 1;
- int need_so = 0;
- struct known_trans *newp;
-
- /* We have to continue looking for the module. */
- if (__gconv_path_elem == NULL)
- __gconv_get_path ();
-
- /* See whether we have to append .so. */
- if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0)
- need_so = 1;
-
- /* Create a new entry. */
- newp = (struct known_trans *) malloc (sizeof (struct known_trans)
- + (__gconv_max_path_elem_len
- + name_len + 3)
- + name_len);
- if (newp != NULL)
- {
- char *cp;
-
- /* Clear the struct. */
- memset (newp, '\0', sizeof (struct known_trans));
-
- /* Store a copy of the module name. */
- newp->info.name = cp = (char *) (newp + 1);
- cp = __mempcpy (cp, trans->name, name_len);
-
- newp->fname = cp;
-
- /* Search in all the directories. */
- for (runp = __gconv_path_elem; runp->name != NULL; ++runp)
- {
- cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name),
- trans->name, name_len);
- if (need_so)
- memcpy (cp, ".so", sizeof (".so"));
-
- if (open_translit (newp) == 0)
- {
- /* We found a module. */
- res = 0;
- break;
- }
- }
-
- if (res)
- newp->fname = NULL;
-
- /* In any case we'll add the entry to our search tree. */
- if (__tsearch (newp, &search_tree, trans_compare) == NULL)
- {
- /* Yickes, this should not happen. Unload the object. */
- res = 1;
- /* XXX unload here. */
- }
- }
- }
-
- __libc_lock_unlock (lock);
-
- return res;
+ /* This function always fails. Transliteration module loading is
+ not implemented. */
+ return 1;
}
--
1.9.3

154
glibc-rh1135842.patch Normal file
View File

@ -0,0 +1,154 @@
commit 41488498b6d9440ee66ab033808cce8323bba7ac
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Sep 3 19:45:43 2014 +0200
CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325]
These changes are based on the fix for BZ #14134 in commit
6e230d11837f3ae7b375ea69d7905f0d18eb79e5.
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 0a410a1..b6327d6 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -297,6 +297,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
$(common-objdir)/iconv/iconv_prog TESTS
+ iconv_modules="$(modules)" \
$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
index 0b5484f..cf80993 100644
--- a/iconvdata/ibm1364.c
+++ b/iconvdata/ibm1364.c
@@ -221,7 +221,8 @@ enum
++rp2; \
\
uint32_t res; \
- if (__builtin_expect (ch < rp2->start, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
+ || __builtin_expect (ch < rp2->start, 0) \
|| (res = DB_TO_UCS4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
{ \
diff --git a/iconvdata/ibm932.c b/iconvdata/ibm932.c
index f5dca59..aa69d65 100644
--- a/iconvdata/ibm932.c
+++ b/iconvdata/ibm932.c
@@ -74,11 +74,12 @@
} \
\
ch = (ch * 0x100) + inptr[1]; \
+ /* ch was less than 0xfd. */ \
+ assert (ch < 0xfd00); \
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
- || __builtin_expect (ch < rp2->start, 0) \
+ if (__builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm932db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, '\1') == 0 && ch !=0)) \
{ \
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
index f46dfb5..461fb5e 100644
--- a/iconvdata/ibm933.c
+++ b/iconvdata/ibm933.c
@@ -162,7 +162,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm933db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
index a8e4e6c..132d816 100644
--- a/iconvdata/ibm935.c
+++ b/iconvdata/ibm935.c
@@ -162,7 +162,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm935db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
index 239be61..69b154d 100644
--- a/iconvdata/ibm937.c
+++ b/iconvdata/ibm937.c
@@ -162,7 +162,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm937db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
index 5d0db36..9936e2c 100644
--- a/iconvdata/ibm939.c
+++ b/iconvdata/ibm939.c
@@ -162,7 +162,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm939db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
diff --git a/iconvdata/ibm943.c b/iconvdata/ibm943.c
index be0c14f..c5d5742 100644
--- a/iconvdata/ibm943.c
+++ b/iconvdata/ibm943.c
@@ -75,11 +75,12 @@
} \
\
ch = (ch * 0x100) + inptr[1]; \
+ /* ch was less than 0xfd. */ \
+ assert (ch < 0xfd00); \
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
- || __builtin_expect (ch < rp2->start, 0) \
+ if (__builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm943db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, '\1') == 0 && ch !=0)) \
{ \
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index c98c929..5dfb69f 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -184,6 +184,24 @@ while read utf8 from filename; do
done < TESTS2
+# Check for crashes in decoders.
+printf '\016\377\377\377\377\377\377\377' > $temp1
+for from in $iconv_modules ; do
+ echo $ac_n "test decoder $from $ac_c"
+ PROG=`eval echo $ICONV`
+ if $PROG < $temp1 >/dev/null 2>&1 ; then
+ : # fall through
+ else
+ status=$?
+ if test $status -gt 1 ; then
+ echo "/FAILED"
+ failed=1
+ continue
+ fi
+ fi
+ echo "OK"
+done
+
exit $failed
# Local Variables:
# mode:shell-script

164
glibc-rh1167569.patch Normal file
View File

@ -0,0 +1,164 @@
commit 33ceaf6187b31ea15284ac65131749e1cb68d2ae
Author: Carlos O'Donell <carlos@redhat.com>
Date: Wed Nov 19 11:44:12 2014 -0500
CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
The function wordexp() fails to properly handle the WRDE_NOCMD
flag when processing arithmetic inputs in the form of "$((... ``))"
where "..." can be anything valid. The backticks in the arithmetic
epxression are evaluated by in a shell even if WRDE_NOCMD forbade
command substitution. This allows an attacker to attempt to pass
dangerous commands via constructs of the above form, and bypass
the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
in exec_comm(), the only place that can execute a shell. All other
checks for WRDE_NOCMD are superfluous and removed.
We expand the testsuite and add 3 new regression tests of roughly
the same form but with a couple of nested levels.
On top of the 3 new tests we add fork validation to the WRDE_NOCMD
testing. If any forks are detected during the execution of a wordexp()
call with WRDE_NOCMD, the test is marked as failed. This is slightly
heuristic since vfork might be used in the future, but it provides a
higher level of assurance that no shells were executed as part of
command substitution with WRDE_NOCMD in effect. In addition it doesn't
require libpthread or libdl, instead we use the public implementation
namespace function __register_atfork (already part of the public ABI
for libpthread).
Tested on x86_64 with no regressions.
(cherry picked from commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c)
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index 4957006..bdd65e4 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -27,6 +27,25 @@
#define IFS " \n\t"
+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
+extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
+
+static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
+{
+ return __register_atfork (prepare, parent, child,
+ &__dso_handle == NULL ? NULL : __dso_handle);
+}
+
+/* Number of forks seen. */
+static int registered_forks;
+
+/* For each fork increment the fork count. */
+static void
+register_fork (void)
+{
+ registered_forks++;
+}
+
struct test_case_struct
{
int retval;
@@ -206,6 +225,12 @@ struct test_case_struct
{ WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
{ WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
{ WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
+ /* Test for CVE-2014-7817. We test 3 combinations of command
+ substitution inside an arithmetic expression to make sure that
+ no commands are executed and error is returned. */
+ { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
+ { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
+ { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
{ -1, NULL, NULL, 0, 0, { NULL, }, IFS },
};
@@ -258,6 +283,15 @@ main (int argc, char *argv[])
return -1;
}
+ /* If we are not allowed to do command substitution, we install
+ fork handlers to verify that no forks happened. No forks should
+ happen at all if command substitution is disabled. */
+ if (__app_register_atfork (register_fork, NULL, NULL) != 0)
+ {
+ printf ("Failed to register fork handler.\n");
+ return -1;
+ }
+
for (test = 0; test_case[test].retval != -1; test++)
if (testit (&test_case[test]))
++fail;
@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
printf ("Test %d (%s): ", ++tests, tc->words);
+ if (tc->flags & WRDE_NOCMD)
+ registered_forks = 0;
+
if (tc->flags & WRDE_APPEND)
{
/* initial wordexp() call, to be appended to */
@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
}
retval = wordexp (tc->words, &we, tc->flags);
+ if ((tc->flags & WRDE_NOCMD)
+ && (registered_forks > 0))
+ {
+ printf ("FAILED fork called for WRDE_NOCMD\n");
+ return 1;
+ }
+
if (tc->flags & WRDE_DOOFFS)
start_offs = sav_we.we_offs;
diff --git a/posix/wordexp.c b/posix/wordexp.c
index b6b65dd..26f3a26 100644
--- a/posix/wordexp.c
+++ b/posix/wordexp.c
@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
pid_t pid;
int noexec = 0;
+ /* Do nothing if command substitution should not succeed. */
+ if (flags & WRDE_NOCMD)
+ return WRDE_CMDSUB;
+
/* Don't fork() unless necessary */
if (!comm || !*comm)
return 0;
@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
}
}
- if (flags & WRDE_NOCMD)
- return WRDE_CMDSUB;
-
(*offset) += 2;
return parse_comm (word, word_length, max_length, words, offset, flags,
quoted? NULL : pwordexp, ifs, ifs_white);
@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length,
break;
case '`':
- if (flags & WRDE_NOCMD)
- return WRDE_CMDSUB;
-
++(*offset);
error = parse_backtick (word, word_length, max_length, words,
offset, flags, NULL, NULL, NULL);
@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
break;
case '`':
- if (flags & WRDE_NOCMD)
- {
- error = WRDE_CMDSUB;
- goto do_error;
- }
-
++words_offset;
error = parse_backtick (&word, &word_length, &max_length, words,
&words_offset, flags, pwordexp, ifs,

View File

@ -0,0 +1,516 @@
#
# Already upstream.
#
# commit 0b1f8e35640f5b3f7af11764ade3ff060211c309
# Author: Carlos O'Donell <carlos@redhat.com>
# Date: Mon Sep 23 01:44:38 2013 -0400
#
# BZ #15754: Fix test case for ARM.
#
# Statically built binaries use __pointer_chk_guard_local,
# while dynamically built binaries use __pointer_chk_guard.
# Provide the right definition depending on the test case
# we are building.
#
# commit c61b4d41c9647a54a329aa021341c0eb032b793e
# Author: Carlos O'Donell <carlos@redhat.com>
# Date: Mon Sep 23 00:52:09 2013 -0400
#
# BZ #15754: CVE-2013-4788
#
# The pointer guard used for pointer mangling was not initialized for
# static applications resulting in the security feature being disabled.
# The pointer guard is now correctly initialized to a random value for
# static applications. Existing static applications need to be
# recompiled to take advantage of the fix.
#
# The test tst-ptrguard1-static and tst-ptrguard1 add regression
# coverage to ensure the pointer guards are sufficiently random
# and initialized to a default value.
#
#
diff --git a/csu/libc-start.c b/csu/libc-start.c
index e5da3ef..c898d06 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -37,6 +37,12 @@ extern void __pthread_initialize_minimal (void);
in thread local area. */
uintptr_t __stack_chk_guard attribute_relro;
# endif
+# ifndef THREAD_SET_POINTER_GUARD
+/* Only exported for architectures that don't store the pointer guard
+ value in thread local area. */
+uintptr_t __pointer_chk_guard_local
+ attribute_relro attribute_hidden __attribute__ ((nocommon));
+# endif
#endif
#ifdef HAVE_PTR_NTHREADS
@@ -195,6 +201,16 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
# else
__stack_chk_guard = stack_chk_guard;
# endif
+
+ /* Set up the pointer guard value. */
+ uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
+ stack_chk_guard);
+# ifdef THREAD_SET_POINTER_GUARD
+ THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+# else
+ __pointer_chk_guard_local = pointer_chk_guard;
+# endif
+
#endif
/* Register the destructor of the dynamic linker if there is any. */
diff --git a/elf/Makefile b/elf/Makefile
index aaa9534..cb8da93 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -121,7 +121,8 @@ endif
tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5
tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \
- tst-leaks1-static tst-array1-static tst-array5-static
+ tst-leaks1-static tst-array1-static tst-array5-static \
+ tst-ptrguard1-static
ifeq (yes,$(build-shared))
tests-static += tst-tls9-static
tst-tls9-static-ENV = \
@@ -145,7 +146,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
tst-audit1 tst-audit2 tst-audit8 \
tst-stackguard1 tst-addr1 tst-thrlock \
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
- tst-initorder tst-initorder2 tst-relsort1 tst-null-argv
+ tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
+ tst-ptrguard1
# reldep9
test-srcs = tst-pathopt
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
@@ -1016,6 +1018,9 @@ LDFLAGS-order2mod2.so = $(no-as-needed)
tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child"
tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
+tst-ptrguard1-ARGS = --command "$(host-test-program-cmd) --child"
+tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child"
+
$(objpfx)tst-leaks1: $(libdl)
$(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@
diff --git a/elf/tst-ptrguard1-static.c b/elf/tst-ptrguard1-static.c
new file mode 100644
index 0000000..7aff3b7
--- /dev/null
+++ b/elf/tst-ptrguard1-static.c
@@ -0,0 +1 @@
+#include "tst-ptrguard1.c"
diff --git a/elf/tst-ptrguard1.c b/elf/tst-ptrguard1.c
new file mode 100644
index 0000000..c344a04
--- /dev/null
+++ b/elf/tst-ptrguard1.c
@@ -0,0 +1,202 @@
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <stackguard-macros.h>
+#include <tls.h>
+#include <unistd.h>
+
+#ifndef POINTER_CHK_GUARD
+extern uintptr_t __pointer_chk_guard;
+# define POINTER_CHK_GUARD __pointer_chk_guard
+#endif
+
+static const char *command;
+static bool child;
+static uintptr_t ptr_chk_guard_copy;
+static bool ptr_chk_guard_copy_set;
+static int fds[2];
+
+static void __attribute__ ((constructor))
+con (void)
+{
+ ptr_chk_guard_copy = POINTER_CHK_GUARD;
+ ptr_chk_guard_copy_set = true;
+}
+
+static int
+uintptr_t_cmp (const void *a, const void *b)
+{
+ if (*(uintptr_t *) a < *(uintptr_t *) b)
+ return 1;
+ if (*(uintptr_t *) a > *(uintptr_t *) b)
+ return -1;
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ if (!ptr_chk_guard_copy_set)
+ {
+ puts ("constructor has not been run");
+ return 1;
+ }
+
+ if (ptr_chk_guard_copy != POINTER_CHK_GUARD)
+ {
+ puts ("POINTER_CHK_GUARD changed between constructor and do_test");
+ return 1;
+ }
+
+ if (child)
+ {
+ write (2, &ptr_chk_guard_copy, sizeof (ptr_chk_guard_copy));
+ return 0;
+ }
+
+ if (command == NULL)
+ {
+ puts ("missing --command or --child argument");
+ return 1;
+ }
+
+#define N 16
+ uintptr_t child_ptr_chk_guards[N + 1];
+ child_ptr_chk_guards[N] = ptr_chk_guard_copy;
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ if (pipe (fds) < 0)
+ {
+ printf ("couldn't create pipe: %m\n");
+ return 1;
+ }
+
+ pid_t pid = fork ();
+ if (pid < 0)
+ {
+ printf ("fork failed: %m\n");
+ return 1;
+ }
+
+ if (!pid)
+ {
+ if (ptr_chk_guard_copy != POINTER_CHK_GUARD)
+ {
+ puts ("POINTER_CHK_GUARD changed after fork");
+ exit (1);
+ }
+
+ close (fds[0]);
+ close (2);
+ dup2 (fds[1], 2);
+ close (fds[1]);
+
+ system (command);
+ exit (0);
+ }
+
+ close (fds[1]);
+
+ if (TEMP_FAILURE_RETRY (read (fds[0], &child_ptr_chk_guards[i],
+ sizeof (uintptr_t))) != sizeof (uintptr_t))
+ {
+ puts ("could not read ptr_chk_guard value from child");
+ return 1;
+ }
+
+ close (fds[0]);
+
+ pid_t termpid;
+ int status;
+ termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
+ if (termpid == -1)
+ {
+ printf ("waitpid failed: %m\n");
+ return 1;
+ }
+ else if (termpid != pid)
+ {
+ printf ("waitpid returned %ld != %ld\n",
+ (long int) termpid, (long int) pid);
+ return 1;
+ }
+ else if (!WIFEXITED (status) || WEXITSTATUS (status))
+ {
+ puts ("child hasn't exited with exit status 0");
+ return 1;
+ }
+ }
+
+ qsort (child_ptr_chk_guards, N + 1, sizeof (uintptr_t), uintptr_t_cmp);
+
+ /* The default pointer guard is the same as the default stack guard.
+ They are only set to default if dl_random is NULL. */
+ uintptr_t default_guard = 0;
+ unsigned char *p = (unsigned char *) &default_guard;
+ p[sizeof (uintptr_t) - 1] = 255;
+ p[sizeof (uintptr_t) - 2] = '\n';
+ p[0] = 0;
+
+ /* Test if the pointer guard canaries are either randomized,
+ or equal to the default pointer guard value.
+ Even with randomized pointer guards it might happen
+ that the random number generator generates the same
+ values, but if that happens in more than half from
+ the 16 runs, something is very wrong. */
+ int ndifferences = 0;
+ int ndefaults = 0;
+ for (i = 0; i < N; ++i)
+ {
+ if (child_ptr_chk_guards[i] != child_ptr_chk_guards[i+1])
+ ndifferences++;
+ else if (child_ptr_chk_guards[i] == default_guard)
+ ndefaults++;
+ }
+
+ printf ("differences %d defaults %d\n", ndifferences, ndefaults);
+
+ if (ndifferences < N / 2 && ndefaults < N / 2)
+ {
+ puts ("pointer guard values are not randomized enough");
+ puts ("nor equal to the default value");
+ return 1;
+ }
+
+ return 0;
+}
+
+#define OPT_COMMAND 10000
+#define OPT_CHILD 10001
+#define CMDLINE_OPTIONS \
+ { "command", required_argument, NULL, OPT_COMMAND }, \
+ { "child", no_argument, NULL, OPT_CHILD },
+#define CMDLINE_PROCESS \
+ case OPT_COMMAND: \
+ command = optarg; \
+ break; \
+ case OPT_CHILD: \
+ child = true; \
+ break;
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/ports/sysdeps/ia64/stackguard-macros.h b/ports/sysdeps/ia64/stackguard-macros.h
index dc683c2..3907293 100644
--- a/ports/sysdeps/ia64/stackguard-macros.h
+++ b/ports/sysdeps/ia64/stackguard-macros.h
@@ -2,3 +2,6 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("adds %0 = -8, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
+
+#define POINTER_CHK_GUARD \
+ ({ uintptr_t x; asm ("adds %0 = -16, r13;; ld8 %0 = [%0]" : "=r" (x)); x; })
diff --git a/ports/sysdeps/tile/stackguard-macros.h b/ports/sysdeps/tile/stackguard-macros.h
index 589ea2b..f2e041b 100644
--- a/ports/sysdeps/tile/stackguard-macros.h
+++ b/ports/sysdeps/tile/stackguard-macros.h
@@ -4,11 +4,17 @@
# if __WORDSIZE == 64
# define STACK_CHK_GUARD \
({ uintptr_t x; asm ("addi %0, tp, -16; ld %0, %0" : "=r" (x)); x; })
+# define POINTER_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -24; ld %0, %0" : "=r" (x)); x; })
# else
# define STACK_CHK_GUARD \
({ uintptr_t x; asm ("addi %0, tp, -8; ld4s %0, %0" : "=r" (x)); x; })
+# define POINTER_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -12; ld4s %0, %0" : "=r" (x)); x; })
# endif
#else
# define STACK_CHK_GUARD \
({ uintptr_t x; asm ("addi %0, tp, -8; lw %0, %0" : "=r" (x)); x; })
+# define POINTER_CHK_GUARD \
+ ({ uintptr_t x; asm ("addi %0, tp, -12; lw %0, %0" : "=r" (x)); x; })
#endif
diff --git a/sysdeps/generic/stackguard-macros.h b/sysdeps/generic/stackguard-macros.h
index ababf65..77408c6 100644
--- a/sysdeps/generic/stackguard-macros.h
+++ b/sysdeps/generic/stackguard-macros.h
@@ -2,3 +2,6 @@
extern uintptr_t __stack_chk_guard;
#define STACK_CHK_GUARD __stack_chk_guard
+
+extern uintptr_t __pointer_chk_guard_local;
+#define POINTER_CHK_GUARD __pointer_chk_guard_local
diff --git a/sysdeps/i386/stackguard-macros.h b/sysdeps/i386/stackguard-macros.h
index 8c31e19..0397629 100644
--- a/sysdeps/i386/stackguard-macros.h
+++ b/sysdeps/i386/stackguard-macros.h
@@ -2,3 +2,11 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("movl %%gs:0x14, %0" : "=r" (x)); x; })
+
+#define POINTER_CHK_GUARD \
+ ({ \
+ uintptr_t x; \
+ asm ("movl %%gs:%c1, %0" : "=r" (x) \
+ : "i" (offsetof (tcbhead_t, pointer_guard))); \
+ x; \
+ })
diff --git a/sysdeps/powerpc/powerpc32/stackguard-macros.h b/sysdeps/powerpc/powerpc32/stackguard-macros.h
index 839f6a4..b3d0af8 100644
--- a/sysdeps/powerpc/powerpc32/stackguard-macros.h
+++ b/sysdeps/powerpc/powerpc32/stackguard-macros.h
@@ -2,3 +2,13 @@
#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; \
+ })
diff --git a/sysdeps/powerpc/powerpc64/stackguard-macros.h b/sysdeps/powerpc/powerpc64/stackguard-macros.h
index 9da879c..4620f96 100644
--- a/sysdeps/powerpc/powerpc64/stackguard-macros.h
+++ b/sysdeps/powerpc/powerpc64/stackguard-macros.h
@@ -2,3 +2,13 @@
#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(2)" \
+ : "=r" (x) \
+ : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \
+ ); \
+ x; \
+ })
diff --git a/sysdeps/s390/s390-32/stackguard-macros.h b/sysdeps/s390/s390-32/stackguard-macros.h
index b74c579..449e8d4 100644
--- a/sysdeps/s390/s390-32/stackguard-macros.h
+++ b/sysdeps/s390/s390-32/stackguard-macros.h
@@ -2,3 +2,14 @@
#define STACK_CHK_GUARD \
({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; })
+
+/* On s390/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; l %0,%1(%0)" \
+ : "=a" (x) \
+ : "i" (offsetof (tcbhead_t, stack_guard))); \
+ x; \
+ })
diff --git a/sysdeps/s390/s390-64/stackguard-macros.h b/sysdeps/s390/s390-64/stackguard-macros.h
index 0cebb5f..c8270fb 100644
--- a/sysdeps/s390/s390-64/stackguard-macros.h
+++ b/sysdeps/s390/s390-64/stackguard-macros.h
@@ -2,3 +2,17 @@
#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 s390/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; \
+ })
diff --git a/sysdeps/sparc/sparc32/stackguard-macros.h b/sysdeps/sparc/sparc32/stackguard-macros.h
index c0b02b0..1eef0f1 100644
--- a/sysdeps/sparc/sparc32/stackguard-macros.h
+++ b/sysdeps/sparc/sparc32/stackguard-macros.h
@@ -2,3 +2,6 @@
#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; })
diff --git a/sysdeps/sparc/sparc64/stackguard-macros.h b/sysdeps/sparc/sparc64/stackguard-macros.h
index 80f0635..cc0c12c 100644
--- a/sysdeps/sparc/sparc64/stackguard-macros.h
+++ b/sysdeps/sparc/sparc64/stackguard-macros.h
@@ -2,3 +2,6 @@
#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; })
diff --git a/sysdeps/x86_64/stackguard-macros.h b/sysdeps/x86_64/stackguard-macros.h
index d7fedb3..1948800 100644
--- a/sysdeps/x86_64/stackguard-macros.h
+++ b/sysdeps/x86_64/stackguard-macros.h
@@ -4,3 +4,8 @@
({ uintptr_t x; \
asm ("mov %%fs:%c1, %0" : "=r" (x) \
: "i" (offsetof (tcbhead_t, stack_guard))); x; })
+
+#define POINTER_CHK_GUARD \
+ ({ uintptr_t x; \
+ asm ("mov %%fs:%c1, %0" : "=r" (x) \
+ : "i" (offsetof (tcbhead_t, pointer_guard))); x; })
diff --git a/elf/Makefile b/elf/Makefile
index cb8da93..27d249b 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1019,6 +1019,9 @@ tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child"
tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child"
tst-ptrguard1-ARGS = --command "$(host-test-program-cmd) --child"
+# When built statically, the pointer guard interface uses
+# __pointer_chk_guard_local.
+CFLAGS-tst-ptrguard1-static.c = -DPTRGUARD_LOCAL
tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child"
$(objpfx)tst-leaks1: $(libdl)
diff --git a/sysdeps/generic/stackguard-macros.h b/sysdeps/generic/stackguard-macros.h
index 4fa3d96..b4a6b23 100644
--- a/sysdeps/generic/stackguard-macros.h
+++ b/sysdeps/generic/stackguard-macros.h
@@ -3,5 +3,10 @@
extern uintptr_t __stack_chk_guard;
#define STACK_CHK_GUARD __stack_chk_guard
+#ifdef PTRGUARD_LOCAL
extern uintptr_t __pointer_chk_guard_local;
-#define POINTER_CHK_GUARD __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

View File

@ -1,6 +1,6 @@
%define glibcsrcdir glibc-2.18
%define glibcversion 2.18
%define glibcrelease 6%{?dist}
%define glibcrelease 19%{?dist}
# Pre-release tarballs are pulled in from git using a command that is
# effectively:
#
@ -180,10 +180,26 @@ Patch0040: %{name}-rh731833-rtkaio.patch
Patch0041: %{name}-rh731833-rtkaio-2.patch
Patch0042: %{name}-rh970865.patch
# ARM: Accept that some objects marked hard ABI are now not because of a
# binutils bug.
Patch0043: %{name}-rh1009145.patch
Patch0044: %{name}-rh1119128.patch
#
# Patches from upstream
#
Patch1001: %{name}-rh995841.patch
Patch1002: %{name}-rh1008299.patch
Patch1003: %{name}-rh1047979.patch
Patch1004: %{name}-rh1055613.patch
Patch1005: %{name}-rh1019452.patch
Patch1006: %{name}-rh1118581.patch
Patch1007: %{name}-rh1118581-2.patch
Patch1008: %{name}-rh1104400.patch
Patch1009: %{name}-rh1135842.patch
Patch1010: %{name}-rh1167569.patch
#
# Patches submitted, but not yet approved upstream.
@ -221,6 +237,11 @@ Patch2029: %{name}-rh1000924.patch
# Pass dl_hwcap to IFUNC resolver on 32-bit ARM.
Patch2030: %{name}-rh985342.patch
# Upstream BZ 15754
Patch2031: %{name}-rh985625-CVE-2013-4788.patch
Patch2032: %{name}-rh1007590.patch
##############################################################################
# End of glibc patches.
##############################################################################
@ -279,9 +300,16 @@ Conflicts: kernel < %{enablekernel}
BuildRequires: binutils >= 2.20.51.0.2
Conflicts: binutils < 2.20.51.0.2
%else
%ifarch s390 s390x
# Needed for STT_GNU_IFUNC support for s390/390x
BuildRequires: binutils >= 2.23.52.0.1-8
Conflicts: binutils < 2.23.52.0.1-8
%else
# Default to this version
BuildRequires: binutils >= 2.19.51.0.10
Conflicts: binutils < 2.19.51.0.10
%endif
%endif
# Earlier releases have broken support for IRELATIVE relocations
Conflicts: prelink < 0.4.2
%else
@ -543,6 +571,19 @@ package or when debugging this package.
%patch0042 -p1
%patch2029 -p1
%patch2030 -p1
%patch1002 -p1
%patch2031 -p1
%patch2032 -p1
%patch0043 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
%patch0044 -p1
%patch1006 -p1
%patch1007 -p1
%patch1008 -p1
%patch1009 -p1
%patch1010 -p1
##############################################################################
# %%prep - Additional prep required...
@ -672,6 +713,11 @@ build()
build_CFLAGS="$BuildFlags -g -O3 $*"
# Some configure checks can spuriously fail for some architectures if
# unwind info is present
#
# At the moment lock elision is temporarily disabled until we work
# out how to update the microcode in early boot to prevent the cpuid
# results from becoming stale. Once this is fixed add back:
# --enable-lock-elision \
configure_CFLAGS="$build_CFLAGS -fno-asynchronous-unwind-tables"
../configure CC="$GCC" CXX="$GXX" CFLAGS="$configure_CFLAGS" \
--prefix=%{_prefix} \
@ -688,7 +734,6 @@ build()
%ifarch ppc64p7
--with-cpu=power7 \
%endif
--enable-lock-elision \
--disable-profile --enable-nss-crypt ||
{ cat config.log; false; }
@ -1628,6 +1673,55 @@ rm -f *.filelist*
%endif
%changelog
* Fri Feb 27 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-19
- wordexp fails to honour WRDE_NOCMD (CVE-2014-7817, #1167569).
* Mon Feb 23 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-18
- Crashes on invalid input in IBM gconv modules (CVE-2014-6040, #1135842).
* Wed Oct 1 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-17
- Fix lll_unlock twice in pthread_cond_broadcast (#1104400).
* Fri Sep 26 2014 Carlos O'Donell <carlos@redhat.com> - 2.18-16
- Disable lock elision support for Intel hardware until microcode
updates can be done in early bootup (#1146967).
* Tue Aug 26 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-15
- Fix failing tst-setlocale3 (#rh1118581).
* Tue Aug 26 2014 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-14
- Remove gconv transliteration loadable modules support (CVE-2014-5119,
#1119128).
- _nl_find_locale: Improve handling of crafted locale names (CVE-2014-0475,
#1118581).
* 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).
- Fix parsing of 0e+0 as float (#1055613).
* Wed Oct 2 2013 Carlos O'Donell <carlos@redhat.com> - 2.18-11
- Allow ldconfig cached objects previously marked as hard or soft
ABI to now become unmarked without raising an error. This works
around a binutils bug that caused objects to become unmarked.
(#1009145)
* Tue Oct 1 2013 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-10
- Fix check for PI mutex on non-x86 systems (#1007590).
* Mon Sep 23 2013 Carlos O'Donell <carlos@redhat.com> - 2.18-9
- Fix CVE-2013-4788: Static applications now support pointer mangling.
Existing static applications must be recompiled (#985625).
* Wed Sep 18 2013 Patsy Franklin <pfrankli@redhat.com> - 2.18-8
- Fix conditional requiring specific binutils for s390/s390x.
* Mon Sep 16 2013 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.18-7
- Fix integer overflows in *valloc and memalign (CVE-2013-4332, #1008299).
* Thu Aug 29 2013 Carlos O'Donell <carlos@redhat.com> - 2.18-6
- Fix Power build (#997531).