Resolves: #1300304
CVE-2015-8778: integer overflow in hcreate and hcreate_r
This commit is contained in:
parent
9f4a81eb45
commit
a5d8db31b4
41
glibc-rh1300304-1.patch
Normal file
41
glibc-rh1300304-1.patch
Normal 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
148
glibc-rh1300304-2.patch
Normal 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
46
glibc-rh1300304-3.patch
Normal 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);
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user