From 68cdc08aec92abf91448a542e06fabbedbb583bf Mon Sep 17 00:00:00 2001 From: root Date: Fri, 31 Aug 2012 00:04:43 +0000 Subject: Fri Aug 31 00:04:43 UTC 2012 --- multilib-testing/lib32-glibc/PKGBUILD | 28 +- .../glibc-2.16-strncasecmp-segfault.patch | 65 ++++ .../lib32-glibc/glibc-2.16-strtod-overflow.patch | 389 +++++++++++++++++++++ 3 files changed, 476 insertions(+), 6 deletions(-) create mode 100644 multilib-testing/lib32-glibc/glibc-2.16-strncasecmp-segfault.patch create mode 100644 multilib-testing/lib32-glibc/glibc-2.16-strtod-overflow.patch (limited to 'multilib-testing') diff --git a/multilib-testing/lib32-glibc/PKGBUILD b/multilib-testing/lib32-glibc/PKGBUILD index 1f71aade3..2f586aeb6 100644 --- a/multilib-testing/lib32-glibc/PKGBUILD +++ b/multilib-testing/lib32-glibc/PKGBUILD @@ -1,4 +1,4 @@ -# $Id: PKGBUILD 75116 2012-08-14 08:29:36Z allan $ +# $Id: PKGBUILD 75727 2012-08-29 17:49:29Z heftig $ # Maintainer: Jan Alexander Steffens (heftig) # Contributor: Jan de Groot # Contributor: Allan McRae @@ -9,7 +9,7 @@ _pkgbasename=glibc pkgname=lib32-$_pkgbasename pkgver=2.16.0 -pkgrel=3 +pkgrel=4 pkgdesc="GNU C Library for multilib" arch=('x86_64') url="http://www.gnu.org/software/libc" @@ -20,12 +20,16 @@ source=(http://ftp.gnu.org/gnu/libc/${_pkgbasename}-${pkgver}.tar.xz{,.sig} glibc-2.15-fix-res_query-assert.patch glibc-2.15-revert-c5a0802a.patch glibc-2.16-rpcgen-cpp-path.patch + glibc-2.16-strncasecmp-segfault.patch + glibc-2.16-strtod-overflow.patch lib32-glibc.conf) md5sums=('80b181b02ab249524ec92822c0174cf7' '2a1221a15575820751c325ef4d2fbb90' '31f415b41197d85d3bbee3d1eecd06a3' '0a0383d50d63f1c02919fe9943b82014' 'ea6a43915474e8276e9361eed6a01280' + 'f042d37cc8ca3459023431809039bc88' + '61d322f7681a85d3293ada5c3ccc2c7e' '6e052f1cb693d5d3203f50f9d4e8c33b') build() { @@ -43,14 +47,26 @@ build() { # http://sourceware.org/git/?p=glibc.git;a=commit;h=bf9b740a patch -p1 -i ${srcdir}/glibc-2.16-rpcgen-cpp-path.patch + # strncasecmp segfault on i686 + # http://sourceware.org/git/?p=glibc.git;a=commit;h=6db8f737 + patch -p1 -i ${srcdir}/glibc-2.16-strncasecmp-segfault.patch + + # strtod integer/buffer overflow + # http://sourceware.org/git/?p=glibc.git;a=commit;h=da1f4319 + patch -p1 -i ${srcdir}/glibc-2.16-strtod-overflow.patch + + # ldconfig does not need to look in /usr/lib64 or /usr/libx32 on Arch Linux + sed -i "s#add_system_dir#do_not_add_system_dir#" sysdeps/unix/sysv/linux/x86_64/dl-cache.h + cd ${srcdir} mkdir glibc-build cd glibc-build - - # Hack to fix NPTL issues with Xen, only required on 32bit platforms - # TODO: make separate glibc-xen package for i686 - export CFLAGS="${CFLAGS} -mno-tls-direct-seg-refs" + #if [[ ${CARCH} = "i686" ]]; then + # Hack to fix NPTL issues with Xen, only required on 32bit platforms + # TODO: make separate glibc-xen package for i686 + export CFLAGS="${CFLAGS} -mno-tls-direct-seg-refs" + #fi export CC="gcc -m32" export CXX="g++ -m32" diff --git a/multilib-testing/lib32-glibc/glibc-2.16-strncasecmp-segfault.patch b/multilib-testing/lib32-glibc/glibc-2.16-strncasecmp-segfault.patch new file mode 100644 index 000000000..ce91bbe82 --- /dev/null +++ b/multilib-testing/lib32-glibc/glibc-2.16-strncasecmp-segfault.patch @@ -0,0 +1,65 @@ +diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c +index 6c17530..acfe668 100644 +--- a/string/test-strncasecmp.c ++++ b/string/test-strncasecmp.c +@@ -1,5 +1,5 @@ + /* Test and measure strncasecmp functions. +- Copyright (C) 1999, 2002, 2003, 2005, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1999-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek , 1999. + +@@ -251,9 +251,9 @@ do_random_tests (void) + } + } + +- ++/* Regression test for BZ #12205 */ + static void +-check1 (void) ++bz12205 (void) + { + static char cp [4096+16] __attribute__ ((aligned(4096))); + static char gotrel[4096] __attribute__ ((aligned(4096))); +@@ -270,6 +270,15 @@ check1 (void) + check_result (impl, s1, s2, n, exp_result); + } + ++/* Regression test for BZ #14195 */ ++static void ++bz14195 (void) ++{ ++ const char *empty_string = ""; ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, empty_string, "", 5, 0); ++} ++ + int + test_main (void) + { +@@ -277,7 +286,8 @@ test_main (void) + + test_init (); + +- check1 (); ++ bz12205 (); ++ bz14195 (); + + printf ("%23s", ""); + FOR_EACH_IMPL (impl, 0) +diff --git a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S b/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +index 5e6321e..9735ad0 100644 +--- a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S ++++ b/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +@@ -2445,7 +2445,7 @@ L(less16bytes_sncmp): + # endif + jne L(neq_sncmp) + test %cl, %cl +- je L(eq) ++ je L(eq_sncmp) + + cmp $1, REM + je L(eq_sncmp) +-- +1.7.3.4 + diff --git a/multilib-testing/lib32-glibc/glibc-2.16-strtod-overflow.patch b/multilib-testing/lib32-glibc/glibc-2.16-strtod-overflow.patch new file mode 100644 index 000000000..526296325 --- /dev/null +++ b/multilib-testing/lib32-glibc/glibc-2.16-strtod-overflow.patch @@ -0,0 +1,389 @@ +diff --git a/stdlib/Makefile b/stdlib/Makefile +index f7811c5..79c9acb 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -68,7 +68,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ + tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ + tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ + tst-makecontext2 tst-strtod6 tst-unsetenv1 \ +- tst-makecontext3 bug-getcontext bug-fmtmsg1 ++ tst-makecontext3 bug-getcontext bug-fmtmsg1 \ ++ tst-strtod-overflow + + include ../Makeconfig + +diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c +index 2166a08..a8a7ea8 100644 +--- a/stdlib/strtod_l.c ++++ b/stdlib/strtod_l.c +@@ -60,6 +60,7 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **, + #include + #include + #include ++#include + + /* The gmp headers need some configuration frobs. */ + #define HAVE_ALLOCA 1 +@@ -72,7 +73,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **, + #include "longlong.h" + #include "fpioconst.h" + +-#define NDEBUG 1 + #include + + +@@ -174,19 +174,19 @@ extern const mp_limb_t _tens_in_limb[MAX_DIG_PER_LIMB + 1]; + /* Return a floating point number of the needed type according to the given + multi-precision number after possible rounding. */ + static FLOAT +-round_and_return (mp_limb_t *retval, int exponent, int negative, ++round_and_return (mp_limb_t *retval, intmax_t exponent, int negative, + mp_limb_t round_limb, mp_size_t round_bit, int more_bits) + { + if (exponent < MIN_EXP - 1) + { +- mp_size_t shift = MIN_EXP - 1 - exponent; +- +- if (shift > MANT_DIG) ++ if (exponent < MIN_EXP - 1 - MANT_DIG) + { + __set_errno (ERANGE); + return 0.0; + } + ++ mp_size_t shift = MIN_EXP - 1 - exponent; ++ + more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0; + if (shift == MANT_DIG) + /* This is a special case to handle the very seldom case where +@@ -233,6 +233,9 @@ round_and_return (mp_limb_t *retval, int exponent, int negative, + __set_errno (ERANGE); + } + ++ if (exponent > MAX_EXP) ++ goto overflow; ++ + if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0 + && (more_bits || (retval[0] & 1) != 0 + || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0)) +@@ -258,6 +261,7 @@ round_and_return (mp_limb_t *retval, int exponent, int negative, + } + + if (exponent > MAX_EXP) ++ overflow: + return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL; + + return MPN2FLOAT (retval, exponent, negative); +@@ -271,7 +275,7 @@ round_and_return (mp_limb_t *retval, int exponent, int negative, + factor for the resulting number (see code) multiply by it. */ + static const STRING_TYPE * + str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize, +- int *exponent ++ intmax_t *exponent + #ifndef USE_WIDE_CHAR + , const char *decimal, size_t decimal_len, const char *thousands + #endif +@@ -301,6 +305,7 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize, + cy += __mpn_add_1 (n, n, *nsize, low); + if (cy != 0) + { ++ assert (*nsize < MPNSIZE); + n[*nsize] = cy; + ++(*nsize); + } +@@ -335,7 +340,7 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize, + } + while (--digcnt > 0); + +- if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB) ++ if (*exponent > 0 && *exponent <= MAX_DIG_PER_LIMB - cnt) + { + low *= _tens_in_limb[*exponent]; + start = _tens_in_limb[cnt + *exponent]; +@@ -355,7 +360,10 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize, + cy = __mpn_mul_1 (n, n, *nsize, start); + cy += __mpn_add_1 (n, n, *nsize, low); + if (cy != 0) +- n[(*nsize)++] = cy; ++ { ++ assert (*nsize < MPNSIZE); ++ n[(*nsize)++] = cy; ++ } + } + + return str; +@@ -413,7 +421,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + { + int negative; /* The sign of the number. */ + MPN_VAR (num); /* MP representation of the number. */ +- int exponent; /* Exponent of the number. */ ++ intmax_t exponent; /* Exponent of the number. */ + + /* Numbers starting `0X' or `0x' have to be processed with base 16. */ + int base = 10; +@@ -435,7 +443,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + /* Points at the character following the integer and fractional digits. */ + const STRING_TYPE *expp; + /* Total number of digit and number of digits in integer part. */ +- int dig_no, int_no, lead_zero; ++ size_t dig_no, int_no, lead_zero; + /* Contains the last character read. */ + CHAR_TYPE c; + +@@ -767,7 +775,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + are all or any is really a fractional digit will be decided + later. */ + int_no = dig_no; +- lead_zero = int_no == 0 ? -1 : 0; ++ lead_zero = int_no == 0 ? (size_t) -1 : 0; + + /* Read the fractional digits. A special case are the 'american + style' numbers like `16.' i.e. with decimal point but without +@@ -789,12 +797,13 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + (base == 16 && ({ CHAR_TYPE lo = TOLOWER (c); + lo >= L_('a') && lo <= L_('f'); }))) + { +- if (c != L_('0') && lead_zero == -1) ++ if (c != L_('0') && lead_zero == (size_t) -1) + lead_zero = dig_no - int_no; + ++dig_no; + c = *++cp; + } + } ++ assert (dig_no <= (uintmax_t) INTMAX_MAX); + + /* Remember start of exponent (if any). */ + expp = cp; +@@ -817,24 +826,80 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + + if (c >= L_('0') && c <= L_('9')) + { +- int exp_limit; ++ intmax_t exp_limit; + + /* Get the exponent limit. */ + if (base == 16) +- exp_limit = (exp_negative ? +- -MIN_EXP + MANT_DIG + 4 * int_no : +- MAX_EXP - 4 * int_no + 4 * lead_zero + 3); ++ { ++ if (exp_negative) ++ { ++ assert (int_no <= (uintmax_t) (INTMAX_MAX ++ + MIN_EXP - MANT_DIG) / 4); ++ exp_limit = -MIN_EXP + MANT_DIG + 4 * (intmax_t) int_no; ++ } ++ else ++ { ++ if (int_no) ++ { ++ assert (lead_zero == 0 ++ && int_no <= (uintmax_t) INTMAX_MAX / 4); ++ exp_limit = MAX_EXP - 4 * (intmax_t) int_no + 3; ++ } ++ else if (lead_zero == (size_t) -1) ++ { ++ /* The number is zero and this limit is ++ arbitrary. */ ++ exp_limit = MAX_EXP + 3; ++ } ++ else ++ { ++ assert (lead_zero ++ <= (uintmax_t) (INTMAX_MAX - MAX_EXP - 3) / 4); ++ exp_limit = (MAX_EXP ++ + 4 * (intmax_t) lead_zero ++ + 3); ++ } ++ } ++ } + else +- exp_limit = (exp_negative ? +- -MIN_10_EXP + MANT_DIG + int_no : +- MAX_10_EXP - int_no + lead_zero + 1); ++ { ++ if (exp_negative) ++ { ++ assert (int_no ++ <= (uintmax_t) (INTMAX_MAX + MIN_10_EXP - MANT_DIG)); ++ exp_limit = -MIN_10_EXP + MANT_DIG + (intmax_t) int_no; ++ } ++ else ++ { ++ if (int_no) ++ { ++ assert (lead_zero == 0 ++ && int_no <= (uintmax_t) INTMAX_MAX); ++ exp_limit = MAX_10_EXP - (intmax_t) int_no + 1; ++ } ++ else if (lead_zero == (size_t) -1) ++ { ++ /* The number is zero and this limit is ++ arbitrary. */ ++ exp_limit = MAX_10_EXP + 1; ++ } ++ else ++ { ++ assert (lead_zero ++ <= (uintmax_t) (INTMAX_MAX - MAX_10_EXP - 1)); ++ exp_limit = MAX_10_EXP + (intmax_t) lead_zero + 1; ++ } ++ } ++ } ++ ++ if (exp_limit < 0) ++ exp_limit = 0; + + do + { +- exponent *= 10; +- exponent += c - L_('0'); +- +- if (__builtin_expect (exponent > exp_limit, 0)) ++ if (__builtin_expect ((exponent > exp_limit / 10 ++ || (exponent == exp_limit / 10 ++ && c - L_('0') > exp_limit % 10)), 0)) + /* The exponent is too large/small to represent a valid + number. */ + { +@@ -843,7 +908,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + /* We have to take care for special situation: a joker + might have written "0.0e100000" which is in fact + zero. */ +- if (lead_zero == -1) ++ if (lead_zero == (size_t) -1) + result = negative ? -0.0 : 0.0; + else + { +@@ -862,6 +927,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + /* NOTREACHED */ + } + ++ exponent *= 10; ++ exponent += c - L_('0'); ++ + c = *++cp; + } + while (c >= L_('0') && c <= L_('9')); +@@ -930,7 +998,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + } + #endif + startp += lead_zero + decimal_len; +- exponent -= base == 16 ? 4 * lead_zero : lead_zero; ++ assert (lead_zero <= (base == 16 ++ ? (uintmax_t) INTMAX_MAX / 4 ++ : (uintmax_t) INTMAX_MAX)); ++ assert (lead_zero <= (base == 16 ++ ? ((uintmax_t) exponent ++ - (uintmax_t) INTMAX_MIN) / 4 ++ : ((uintmax_t) exponent - (uintmax_t) INTMAX_MIN))); ++ exponent -= base == 16 ? 4 * (intmax_t) lead_zero : (intmax_t) lead_zero; + dig_no -= lead_zero; + } + +@@ -972,7 +1047,10 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + } + + /* Adjust the exponent for the bits we are shifting in. */ +- exponent += bits - 1 + (int_no - 1) * 4; ++ assert (int_no <= (uintmax_t) (exponent < 0 ++ ? (INTMAX_MAX - bits + 1) / 4 ++ : (INTMAX_MAX - exponent - bits + 1) / 4)); ++ exponent += bits - 1 + ((intmax_t) int_no - 1) * 4; + + while (--dig_no > 0 && idx >= 0) + { +@@ -1024,13 +1102,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + really integer digits or belong to the fractional part; i.e. we normalize + 123e-2 to 1.23. */ + { +- register int incr = (exponent < 0 ? MAX (-int_no, exponent) +- : MIN (dig_no - int_no, exponent)); ++ register intmax_t incr = (exponent < 0 ++ ? MAX (-(intmax_t) int_no, exponent) ++ : MIN ((intmax_t) dig_no - (intmax_t) int_no, ++ exponent)); + int_no += incr; + exponent -= incr; + } + +- if (__builtin_expect (int_no + exponent > MAX_10_EXP + 1, 0)) ++ if (__builtin_expect (exponent > MAX_10_EXP + 1 - (intmax_t) int_no, 0)) + { + __set_errno (ERANGE); + return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL; +@@ -1215,7 +1295,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + digits we should have enough bits for the result. The remaining + decimal digits give us the information that more bits are following. + This can be used while rounding. (Two added as a safety margin.) */ +- if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 2) ++ if ((intmax_t) dig_no > (intmax_t) int_no + (MANT_DIG - bits + 2) / 3 + 2) + { + dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 2; + more_bits = 1; +@@ -1223,7 +1303,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) + else + more_bits = 0; + +- neg_exp = dig_no - int_no - exponent; ++ neg_exp = (intmax_t) dig_no - (intmax_t) int_no - exponent; + + /* Construct the denominator. */ + densize = 0; +diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c +new file mode 100644 +index 0000000..668d55b +--- /dev/null ++++ b/stdlib/tst-strtod-overflow.c +@@ -0,0 +1,48 @@ ++/* Test for integer/buffer overflow in strtod. ++ Copyright (C) 2012 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 ++ . */ ++ ++#include ++#include ++#include ++ ++#define EXPONENT "e-2147483649" ++#define SIZE 214748364 ++ ++static int ++do_test (void) ++{ ++ char *p = malloc (1 + SIZE + sizeof (EXPONENT)); ++ if (p == NULL) ++ { ++ puts ("malloc failed, cannot test for overflow"); ++ return 0; ++ } ++ p[0] = '1'; ++ memset (p + 1, '0', SIZE); ++ memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT)); ++ double d = strtod (p, NULL); ++ if (d != 0) ++ { ++ printf ("strtod returned wrong value: %a\n", d); ++ return 1; ++ } ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +-- +1.7.3.4 + -- cgit v1.2.3