(CVE-2012-4412) glibc: strcoll() integer overflow leading to buffer overflow
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GLibC |
Fix Released
|
Medium
|
|||
Fedora |
Won't Fix
|
Medium
|
|||
Gentoo Linux |
Fix Released
|
High
|
|||
eglibc (Debian) |
Fix Released
|
Unknown
|
|||
eglibc (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
An integer overflow, leading to buffer overflow flaw was found in the way the implementation of strcoll() routine, used to compare two strings based on the current locale, of glibc, the GNU libc libraries, performed calculation of memory requirements / allocation, needed for storage of the strings. If an application linked against glibc was missing an application-level sanity checks for validity of strcoll() arguments and accepted untrusted input, an attacker could use this flaw to cause the particular application to crash or, potentially, execute arbitrary code with the privileges of the user running the application.
Upstream bug report (including reproducer):
[1] http://
Changed in eglibc (Ubuntu): | |
status: | New → Confirmed |
Changed in gentoo: | |
importance: | Unknown → High |
Changed in glibc: | |
importance: | Unknown → Medium |
status: | Unknown → Confirmed |
Changed in eglibc (Debian): | |
status: | Unknown → New |
Changed in glibc: | |
status: | Confirmed → Fix Released |
information type: | Private Security → Public Security |
Changed in eglibc (Debian): | |
status: | New → Fix Released |
Changed in gentoo: | |
status: | Unknown → Fix Released |
Changed in fedora: | |
importance: | Unknown → Medium |
status: | Unknown → Confirmed |
Changed in fedora: | |
status: | Confirmed → Won't Fix |
The code in string/strcoll_l.c that computes a memory allocation size as (s1len + s2len) * (sizeof (int32_t) + 1) fails to allow for possible integer overflow in this computation. On a 32-bit host this can cause too-small allocations and consequent buffer overflow if the strings total more than 0.8GB. Testcase:
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 429496730
int
main (void)
{
char *p = malloc (1 + SIZE);
if (setlocale (LC_COLLATE, "en_GB.UTF-8") == NULL)
{
puts ("setlocale failed, cannot test for overflow");
return 0;
}
if (p == NULL)
{
puts ("malloc failed, cannot test for overflow");
return 0;
}
memset (p, 'x', SIZE);
p[SIZE] = 0;
printf ("%d\n", strcoll (p, p));
return 0;
}