CVE-2015-8778: integer overflow in hcreate and hcreate_r
This commit is contained in:
Florian Weimer 2016-05-07 16:11:33 +02:00
parent 9f4a81eb45
commit a5d8db31b4
4 changed files with 242 additions and 0 deletions

41
glibc-rh1300304-1.patch Normal file
View File

@ -0,0 +1,41 @@
commit 2f5c1750558fe64bac361f52d6827ab1bcfe52bc
Author: Ondřej Bílka <neleai@seznam.cz>
Date: Sat Jul 11 17:44:10 2015 +0200
Handle overflow in __hcreate_r
Hi,
As in bugzilla entry there is overflow in hsearch when looking for prime
number as SIZE_MAX - 1 is divisible by 5. We fix that by rejecting large
inputs before looking for prime.
* misc/hsearch_r.c (__hcreate_r): Handle overflow.
diff --git a/misc/hsearch_r.c b/misc/hsearch_r.c
index 9f55e84..559df29 100644
--- a/misc/hsearch_r.c
+++ b/misc/hsearch_r.c
@@ -19,7 +19,7 @@
#include <errno.h>
#include <malloc.h>
#include <string.h>
-
+#include <stdint.h>
#include <search.h>
/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -73,6 +73,13 @@ __hcreate_r (nel, htab)
return 0;
}
+ if (nel >= SIZE_MAX / sizeof (_ENTRY))
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+
+
/* There is still another table active. Return with error. */
if (htab->table != NULL)
return 0;

148
glibc-rh1300304-2.patch Normal file
View File

@ -0,0 +1,148 @@
commit bae7c7c764413b23e61cb099ce33be4c4ee259bb
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Jan 28 13:59:11 2016 +0100
Improve check against integer wraparound in hcreate_r [BZ #18240]
Index: b/misc/bug18240.c
===================================================================
--- /dev/null
+++ b/misc/bug18240.c
@@ -0,0 +1,75 @@
+/* Test integer wraparound in hcreate.
+ Copyright (C) 2016 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 <limits.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void
+test_size (size_t size)
+{
+ int res = hcreate (size);
+ if (res == 0)
+ {
+ if (errno == ENOMEM)
+ return;
+ printf ("error: hcreate (%zu): %m\n", size);
+ exit (1);
+ }
+ char *keys[100];
+ for (int i = 0; i < 100; ++i)
+ {
+ if (asprintf (keys + i, "%d", i) < 0)
+ {
+ printf ("error: asprintf: %m\n");
+ exit (1);
+ }
+ ENTRY e = { keys[i], (char *) "value" };
+ if (hsearch (e, ENTER) == NULL)
+ {
+ printf ("error: hsearch (\"%s\"): %m\n", keys[i]);
+ exit (1);
+ }
+ }
+ hdestroy ();
+
+ for (int i = 0; i < 100; ++i)
+ free (keys[i]);
+}
+
+static int
+do_test (void)
+{
+ test_size (500);
+ test_size (-1);
+ test_size (-3);
+ test_size (INT_MAX - 2);
+ test_size (INT_MAX - 1);
+ test_size (INT_MAX);
+ test_size (((unsigned) INT_MAX) + 1);
+ test_size (UINT_MAX - 2);
+ test_size (UINT_MAX - 1);
+ test_size (UINT_MAX);
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: b/misc/hsearch_r.c
===================================================================
--- a/misc/hsearch_r.c
+++ b/misc/hsearch_r.c
@@ -46,15 +46,12 @@ static int
isprime (unsigned int number)
{
/* no even number will be passed */
- unsigned int div = 3;
-
- while (div * div < number && number % div != 0)
- div += 2;
-
- return number % div != 0;
+ for (unsigned int div = 3; div <= number / div; div += 2)
+ if (number % div == 0)
+ return 0;
+ return 1;
}
-
/* Before using the hash table we must allocate memory for it.
Test for an existing table are done. We allocate one element
more as the found prime number says. This is done for more effective
@@ -73,13 +70,6 @@ __hcreate_r (nel, htab)
return 0;
}
- if (nel >= SIZE_MAX / sizeof (_ENTRY))
- {
- __set_errno (ENOMEM);
- return 0;
- }
-
-
/* There is still another table active. Return with error. */
if (htab->table != NULL)
return 0;
@@ -88,10 +78,19 @@ __hcreate_r (nel, htab)
use will not work. */
if (nel < 3)
nel = 3;
- /* Change nel to the first prime number not smaller as nel. */
- nel |= 1; /* make odd */
- while (!isprime (nel))
- nel += 2;
+
+ /* Change nel to the first prime number in the range [nel, UINT_MAX - 2],
+ The '- 2' means 'nel += 2' cannot overflow. */
+ for (nel |= 1; ; nel += 2)
+ {
+ if (UINT_MAX - 2 < nel)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+ if (isprime (nel))
+ break;
+ }
htab->size = nel;
htab->filled = 0;

46
glibc-rh1300304-3.patch Normal file
View File

@ -0,0 +1,46 @@
commit f34f146e682d8d529dcf64b3c2781bf3f2f05f6c
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Feb 12 12:57:40 2016 +0100
hsearch_r: Apply VM size limit in test case
diff --git a/misc/bug18240.c b/misc/bug18240.c
index 4b26865..773586e 100644
--- a/misc/bug18240.c
+++ b/misc/bug18240.c
@@ -22,6 +22,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/resource.h>
static void
test_size (size_t size)
@@ -58,6 +59,27 @@ test_size (size_t size)
static int
do_test (void)
{
+ /* Limit the size of the process, so that memory allocation will
+ fail without impacting the entire system. */
+ {
+ struct rlimit limit;
+ if (getrlimit (RLIMIT_AS, &limit) != 0)
+ {
+ printf ("getrlimit (RLIMIT_AS) failed: %m\n");
+ return 1;
+ }
+ long target = 100 * 1024 * 1024;
+ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
+ {
+ limit.rlim_cur = target;
+ if (setrlimit (RLIMIT_AS, &limit) != 0)
+ {
+ printf ("setrlimit (RLIMIT_AS) failed: %m\n");
+ return 1;
+ }
+ }
+ }
+
test_size (500);
test_size (-1);
test_size (-3);

View File

@ -260,6 +260,9 @@ Patch1037: glibc-rh1300311-3.patch
Patch1038: glibc-rh1300311-4.patch
Patch1039: glibc-rh1293139.patch
Patch1040: glibc-rh1300300.patch
Patch1041: glibc-rh1300304-1.patch
Patch1042: glibc-rh1300304-2.patch
Patch1043: glibc-rh1300304-3.patch
##############################################################################
#
@ -719,6 +722,9 @@ microbenchmark tests on the system.
%patch1038 -p1
%patch1039 -p1
%patch1040 -p1
%patch1041 -p1
%patch1042 -p1
%patch1043 -p1
%patch0059 -p1
##############################################################################
@ -1945,6 +1951,7 @@ rm -f *.filelist*
- CVE-2014-9761: unbounded stack allocation in nan* functions (#1300311)
- Fix invalid memory access in getmntent_r (#1293139)
- CVE-2015-8776: crash with invalid data in strftime (#1300300)
- CVE-2015-8778: integer overflow in hcreate and hcreate_r (#1300304)
* Fri May 6 2016 Florian Weimer <fweimer@redhat.com> - 2.22-14
- Fix getnameinfo memory leak and incorrect truncation (#1333901)