aboutsummaryrefslogtreecommitdiff
path: root/string/strcoll_l.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-09-23 11:24:30 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-09-23 11:29:53 +0530
commit303e567a8062200dc06acde7c76fc34679f08d8f (patch)
tree8e0c198956de9addb51216c5cfccd47d7c4be69b /string/strcoll_l.c
parent141f3a77fe4f1b59b0afa9bf6909cd2000448883 (diff)
downloadglibc-303e567a8062200dc06acde7c76fc34679f08d8f.zip
glibc-303e567a8062200dc06acde7c76fc34679f08d8f.tar.gz
glibc-303e567a8062200dc06acde7c76fc34679f08d8f.tar.bz2
Check for integer overflow in cache size computation in strcoll
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. Fixes CVE-2012-4412.
Diffstat (limited to 'string/strcoll_l.c')
-rw-r--r--string/strcoll_l.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/string/strcoll_l.c b/string/strcoll_l.c
index eb042ff..4ee101a 100644
--- 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));