mirror of
https://git.yoctoproject.org/git/poky
synced 2026-01-01 13:58:04 +00:00
glibc: CVE-2015-9761
A stack overflow vulnerability was found in nan* functions that could cause applications which process long strings with the nan function to crash or, potentially, execute arbitrary code. (From OE-Core rev: fd3da8178c8c06b549dbc19ecec40e98ab934d49) (From OE-Core rev: 1916b4c34ee9d752c12b8311cb9fd41e09b82900) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
parent
14a42e2719
commit
204ad23574
1039
meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch
Normal file
1039
meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch
Normal file
File diff suppressed because it is too large
Load Diff
388
meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch
Normal file
388
meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
From 8f5e8b01a1da2a207228f2072c934fa5918554b8 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Myers <joseph@codesourcery.com>
|
||||
Date: Fri, 4 Dec 2015 20:36:28 +0000
|
||||
Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug
|
||||
16962).
|
||||
|
||||
The nan, nanf and nanl functions handle payload strings by doing e.g.:
|
||||
|
||||
if (tagp[0] != '\0')
|
||||
{
|
||||
char buf[6 + strlen (tagp)];
|
||||
sprintf (buf, "NAN(%s)", tagp);
|
||||
return strtod (buf, NULL);
|
||||
}
|
||||
|
||||
This is an unbounded stack allocation based on the length of the
|
||||
argument. Furthermore, if the argument starts with an n-char-sequence
|
||||
followed by ')', that n-char-sequence is wrongly treated as
|
||||
significant for determining the payload of the resulting NaN, when ISO
|
||||
C says the call should be equivalent to strtod ("NAN", NULL), without
|
||||
being affected by that initial n-char-sequence. This patch fixes both
|
||||
those problems by using the __strtod_nan etc. functions recently
|
||||
factored out of strtod etc. for that purpose, with those functions
|
||||
being exported from libc at version GLIBC_PRIVATE.
|
||||
|
||||
Tested for x86_64, x86, mips64 and powerpc.
|
||||
|
||||
[BZ #16961]
|
||||
[BZ #16962]
|
||||
* math/s_nan.c (__nan): Use __strtod_nan instead of constructing a
|
||||
string on the stack for strtod.
|
||||
* math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing
|
||||
a string on the stack for strtof.
|
||||
* math/s_nanl.c (__nanl): Use __strtold_nan instead of
|
||||
constructing a string on the stack for strtold.
|
||||
* stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and
|
||||
__strtold_nan to GLIBC_PRIVATE.
|
||||
* math/test-nan-overflow.c: New file.
|
||||
* math/test-nan-payload.c: Likewise.
|
||||
* math/Makefile (tests): Add test-nan-overflow and
|
||||
test-nan-payload.
|
||||
|
||||
Upstream-Status: Backport
|
||||
CVE: CVE-2015-9761 patch #2
|
||||
[Yocto # 8980]
|
||||
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8f5e8b01a1da2a207228f2072c934fa5918554b8
|
||||
|
||||
Signed-off-by: Armin Kuster <akuster@mvista.com>
|
||||
|
||||
---
|
||||
ChangeLog | 17 +++++++
|
||||
NEWS | 6 +++
|
||||
math/Makefile | 3 +-
|
||||
math/s_nan.c | 9 +---
|
||||
math/s_nanf.c | 9 +---
|
||||
math/s_nanl.c | 9 +---
|
||||
math/test-nan-overflow.c | 66 +++++++++++++++++++++++++
|
||||
math/test-nan-payload.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
stdlib/Versions | 1 +
|
||||
9 files changed, 217 insertions(+), 25 deletions(-)
|
||||
create mode 100644 math/test-nan-overflow.c
|
||||
create mode 100644 math/test-nan-payload.c
|
||||
|
||||
Index: git/ChangeLog
|
||||
===================================================================
|
||||
--- git.orig/ChangeLog
|
||||
+++ git/ChangeLog
|
||||
@@ -1,3 +1,20 @@
|
||||
+2015-12-04 Joseph Myers <joseph@codesourcery.com>
|
||||
+
|
||||
+ [BZ #16961]
|
||||
+ [BZ #16962]
|
||||
+ * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a
|
||||
+ string on the stack for strtod.
|
||||
+ * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing
|
||||
+ a string on the stack for strtof.
|
||||
+ * math/s_nanl.c (__nanl): Use __strtold_nan instead of
|
||||
+ constructing a string on the stack for strtold.
|
||||
+ * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and
|
||||
+ __strtold_nan to GLIBC_PRIVATE.
|
||||
+ * math/test-nan-overflow.c: New file.
|
||||
+ * math/test-nan-payload.c: Likewise.
|
||||
+ * math/Makefile (tests): Add test-nan-overflow and
|
||||
+ test-nan-payload.
|
||||
+
|
||||
2015-11-24 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* stdlib/strtod_nan.c: New file.
|
||||
Index: git/NEWS
|
||||
===================================================================
|
||||
--- git.orig/NEWS
|
||||
+++ git/NEWS
|
||||
@@ -7,6 +7,12 @@ using `glibc' in the "product" field.
|
||||
|
||||
Version 2.21
|
||||
|
||||
+Security related changes:
|
||||
+
|
||||
+* The nan, nanf and nanl functions no longer have unbounded stack usage
|
||||
+ depending on the length of the string passed as an argument to the
|
||||
+ functions. Reported by Joseph Myers.
|
||||
+
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498,
|
||||
Index: git/math/s_nan.c
|
||||
===================================================================
|
||||
--- git.orig/math/s_nan.c
|
||||
+++ git/math/s_nan.c
|
||||
@@ -28,14 +28,7 @@
|
||||
double
|
||||
__nan (const char *tagp)
|
||||
{
|
||||
- if (tagp[0] != '\0')
|
||||
- {
|
||||
- char buf[6 + strlen (tagp)];
|
||||
- sprintf (buf, "NAN(%s)", tagp);
|
||||
- return strtod (buf, NULL);
|
||||
- }
|
||||
-
|
||||
- return NAN;
|
||||
+ return __strtod_nan (tagp, NULL, 0);
|
||||
}
|
||||
weak_alias (__nan, nan)
|
||||
#ifdef NO_LONG_DOUBLE
|
||||
Index: git/math/s_nanf.c
|
||||
===================================================================
|
||||
--- git.orig/math/s_nanf.c
|
||||
+++ git/math/s_nanf.c
|
||||
@@ -28,13 +28,6 @@
|
||||
float
|
||||
__nanf (const char *tagp)
|
||||
{
|
||||
- if (tagp[0] != '\0')
|
||||
- {
|
||||
- char buf[6 + strlen (tagp)];
|
||||
- sprintf (buf, "NAN(%s)", tagp);
|
||||
- return strtof (buf, NULL);
|
||||
- }
|
||||
-
|
||||
- return NAN;
|
||||
+ return __strtof_nan (tagp, NULL, 0);
|
||||
}
|
||||
weak_alias (__nanf, nanf)
|
||||
Index: git/math/s_nanl.c
|
||||
===================================================================
|
||||
--- git.orig/math/s_nanl.c
|
||||
+++ git/math/s_nanl.c
|
||||
@@ -28,13 +28,6 @@
|
||||
long double
|
||||
__nanl (const char *tagp)
|
||||
{
|
||||
- if (tagp[0] != '\0')
|
||||
- {
|
||||
- char buf[6 + strlen (tagp)];
|
||||
- sprintf (buf, "NAN(%s)", tagp);
|
||||
- return strtold (buf, NULL);
|
||||
- }
|
||||
-
|
||||
- return NAN;
|
||||
+ return __strtold_nan (tagp, NULL, 0);
|
||||
}
|
||||
weak_alias (__nanl, nanl)
|
||||
Index: git/math/test-nan-overflow.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/math/test-nan-overflow.c
|
||||
@@ -0,0 +1,66 @@
|
||||
+/* Test nan functions stack overflow (bug 16962).
|
||||
+ Copyright (C) 2015 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 <math.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/resource.h>
|
||||
+
|
||||
+#define STACK_LIM 1048576
|
||||
+#define STRING_SIZE (2 * STACK_LIM)
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ struct rlimit lim;
|
||||
+ getrlimit (RLIMIT_STACK, &lim);
|
||||
+ lim.rlim_cur = STACK_LIM;
|
||||
+ setrlimit (RLIMIT_STACK, &lim);
|
||||
+ char *nanstr = malloc (STRING_SIZE);
|
||||
+ if (nanstr == NULL)
|
||||
+ {
|
||||
+ puts ("malloc failed, cannot test");
|
||||
+ return 77;
|
||||
+ }
|
||||
+ memset (nanstr, '0', STRING_SIZE - 1);
|
||||
+ nanstr[STRING_SIZE - 1] = 0;
|
||||
+#define NAN_TEST(TYPE, FUNC) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ char *volatile p = nanstr; \
|
||||
+ volatile TYPE v = FUNC (p); \
|
||||
+ if (isnan (v)) \
|
||||
+ puts ("PASS: " #FUNC); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #FUNC); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+ NAN_TEST (float, nanf);
|
||||
+ NAN_TEST (double, nan);
|
||||
+#ifndef NO_LONG_DOUBLE
|
||||
+ NAN_TEST (long double, nanl);
|
||||
+#endif
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
Index: git/math/test-nan-payload.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/math/test-nan-payload.c
|
||||
@@ -0,0 +1,122 @@
|
||||
+/* Test nan functions payload handling (bug 16961).
|
||||
+ Copyright (C) 2015 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 <float.h>
|
||||
+#include <math.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Avoid built-in functions. */
|
||||
+#define WRAP_NAN(FUNC, STR) \
|
||||
+ ({ const char *volatile wns = (STR); FUNC (wns); })
|
||||
+#define WRAP_STRTO(FUNC, STR) \
|
||||
+ ({ const char *volatile wss = (STR); FUNC (wss, NULL); })
|
||||
+
|
||||
+#define CHECK_IS_NAN(TYPE, A) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (isnan (A)) \
|
||||
+ puts ("PASS: " #TYPE " " #A); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " " #A); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define CHECK_SAME_NAN(TYPE, A, B) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (memcmp (&(A), &(B), sizeof (A)) == 0) \
|
||||
+ puts ("PASS: " #TYPE " " #A " = " #B); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " " #A " = " #B); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+#define CHECK_DIFF_NAN(TYPE, A, B) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if (memcmp (&(A), &(B), sizeof (A)) != 0) \
|
||||
+ puts ("PASS: " #TYPE " " #A " != " #B); \
|
||||
+ else \
|
||||
+ { \
|
||||
+ puts ("FAIL: " #TYPE " " #A " != " #B); \
|
||||
+ result = 1; \
|
||||
+ } \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+/* Cannot test payloads by memcmp for formats where NaNs have padding
|
||||
+ bits. */
|
||||
+#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
|
||||
+
|
||||
+#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ TYPE n123 = WRAP_NAN (FUNC, "123"); \
|
||||
+ CHECK_IS_NAN (TYPE, n123); \
|
||||
+ TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \
|
||||
+ CHECK_IS_NAN (TYPE, s123); \
|
||||
+ TYPE n456 = WRAP_NAN (FUNC, "456"); \
|
||||
+ CHECK_IS_NAN (TYPE, n456); \
|
||||
+ TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
|
||||
+ CHECK_IS_NAN (TYPE, s456); \
|
||||
+ TYPE n123x = WRAP_NAN (FUNC, "123)"); \
|
||||
+ CHECK_IS_NAN (TYPE, n123x); \
|
||||
+ TYPE nemp = WRAP_NAN (FUNC, ""); \
|
||||
+ CHECK_IS_NAN (TYPE, nemp); \
|
||||
+ TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \
|
||||
+ CHECK_IS_NAN (TYPE, semp); \
|
||||
+ TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \
|
||||
+ CHECK_IS_NAN (TYPE, sx); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, n123, s123); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, n456, s456); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, nemp, semp); \
|
||||
+ if (CAN_TEST_EQ (MANT_DIG)) \
|
||||
+ CHECK_SAME_NAN (TYPE, n123x, sx); \
|
||||
+ CHECK_DIFF_NAN (TYPE, n123, n456); \
|
||||
+ CHECK_DIFF_NAN (TYPE, n123, nemp); \
|
||||
+ CHECK_DIFF_NAN (TYPE, n123, n123x); \
|
||||
+ CHECK_DIFF_NAN (TYPE, n456, nemp); \
|
||||
+ CHECK_DIFF_NAN (TYPE, n456, n123x); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
|
||||
+ RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
|
||||
+#ifndef NO_LONG_DOUBLE
|
||||
+ RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
|
||||
+#endif
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
Index: git/stdlib/Versions
|
||||
===================================================================
|
||||
--- git.orig/stdlib/Versions
|
||||
+++ git/stdlib/Versions
|
||||
@@ -118,5 +118,6 @@ libc {
|
||||
# Used from other libraries
|
||||
__libc_secure_getenv;
|
||||
__call_tls_dtors;
|
||||
+ __strtof_nan; __strtod_nan; __strtold_nan;
|
||||
}
|
||||
}
|
||||
Index: git/math/Makefile
|
||||
===================================================================
|
||||
--- git.orig/math/Makefile
|
||||
+++ git/math/Makefile
|
||||
@@ -92,7 +92,9 @@ tests = test-matherr test-fenv atest-exp
|
||||
test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \
|
||||
test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \
|
||||
test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \
|
||||
- test-fenv-tls test-fenv-preserve test-fenv-return $(tests-static)
|
||||
+ test-fenv-tls test-fenv-preserve test-fenv-return \
|
||||
+ test-nan-overflow test-nan-payload \
|
||||
+ $(tests-static)
|
||||
tests-static = test-fpucw-static test-fpucw-ieee-static
|
||||
# We do the `long double' tests only if this data type is available and
|
||||
# distinct from `double'.
|
||||
|
|
@ -50,6 +50,8 @@ CVEPATCHES = "\
|
|||
file://CVE-2015-7547.patch \
|
||||
file://CVE-2015-8777.patch \
|
||||
file://CVE-2015-8779.patch \
|
||||
file://CVE-2015-9761_1.patch \
|
||||
file://CVE-2015-9761_2.patch \
|
||||
"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://LICENSES;md5=e9a558e243b36d3209f380deb394b213 \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user