summaryrefslogtreecommitdiffstats
path: root/patches/source/glibc/glibc-2.17_CVE-2012-4412.diff
diff options
context:
space:
mode:
Diffstat (limited to 'patches/source/glibc/glibc-2.17_CVE-2012-4412.diff')
-rw-r--r--patches/source/glibc/glibc-2.17_CVE-2012-4412.diff116
1 files changed, 116 insertions, 0 deletions
diff --git a/patches/source/glibc/glibc-2.17_CVE-2012-4412.diff b/patches/source/glibc/glibc-2.17_CVE-2012-4412.diff
new file mode 100644
index 000000000..107302c78
--- /dev/null
+++ b/patches/source/glibc/glibc-2.17_CVE-2012-4412.diff
@@ -0,0 +1,116 @@
+From 40790558474490d9d1aee5502cccb92e1c45e196 Mon Sep 17 00:00:00 2001
+From: mancha <mancha1@hush.com>
+Date: Wed, 23 Oct 2013
+Subject: CVE-2012-4412
+
+strcoll is implemented using a cache for indices and weights of
+collation sequences in the strings so that subsequent passes do not
+have to search through collation data again. For very large string
+inputs, the cache size computation could overflow. In such a case,
+use the fallback function that does not cache indices and weights of
+collation sequences.
+
+---
+This patch was adapted for glibc 2.17 based on:
+https://sourceware.org/git/?p=glibc.git;a=commit;h=303e567a8062
+---
+
+ Makefile | 2 +
+ strcoll_l.c | 10 +++++++-
+ tst-strcoll-overflow.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+), 1 deletion(-)
+
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -61,6 +61,8 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
+ tests-ifunc := $(strop-tests:%=test-%-ifunc)
+ tests += $(tests-ifunc)
+
++xtests = tst-strcoll-overflow
++
+ include ../Rules
+
+ tester-ENV = LANGUAGE=C
+--- a/string/strcoll_l.c
++++ b/string/strcoll_l.c
+@@ -524,7 +524,15 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+ memset (&seq1, 0, sizeof (seq1));
+ seq2 = seq1;
+
+- if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
++ size_t size_max = SIZE_MAX / (sizeof (int32_t) + 1);
++
++ if (MIN (s1len, s2len) > size_max
++ || MAX (s1len, s2len) > size_max - MIN (s1len, s2len))
++ {
++ /* If the strings are long enough to cause overflow in the size request,
++ then skip the allocation and proceed with the non-cached routines. */
++ }
++ else if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1)))
+ {
+ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1));
+
+--- /dev/null
++++ b/string/tst-strcoll-overflow.c
+@@ -0,0 +1,61 @@
++/* 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 <locale.h>
++#include <stdio.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++
++/* Verify that strcoll does not crash for large strings for which it cannot
++ cache weight lookup results. The size is large enough to cause integer
++ overflows on 32-bit as well as buffer overflows on 64-bit. The test should
++ work reasonably reliably when overcommit is disabled, but it obviously
++ depends on how much memory the system has. There's a limitation to this
++ test in that it does not run to completion. Actually collating such a
++ large string can take days and we can't have xcheck running that long. For
++ that reason, we run the test for about 5 minutes and then assume that
++ everything is fine if there are no crashes. */
++#define SIZE 0x40000000ul
++
++int
++do_test (void)
++{
++ if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL)
++ {
++ puts ("setlocale failed, cannot test for overflow");
++ return 0;
++ }
++
++ char *p = malloc (SIZE);
++
++ if (p == NULL)
++ {
++ puts ("could not allocate memory");
++ return 1;
++ }
++
++ memset (p, 'x', SIZE - 1);
++ p[SIZE - 1] = 0;
++ printf ("%d\n", strcoll (p, p));
++ return 0;
++}
++
++#define TIMEOUT 300
++#define EXPECTED_SIGNAL SIGALRM
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"