Fix _nl_find_msg malloc failure case, and callers.
This patch fixes two issues, and perhaps should be two distinct commits,
but I present it here as one for the sake of completeness.
Commit 006dd86111
fails to check malloc's
return in intl/dcigettext.c (_nl_find_msg):
~~~
freemem_size = INITIAL_BLOCK_SIZE;
newmem = (transmem_block_t *) malloc (freemem_size);
...
newmem->next = transmem_list;
transmem_list = newmem;
~~~
If malloc fails then newmem is NULL then newmem->next results in a
fault.
The fix is easy enough, check for newmem != NULL, and fall through to
the error condition below which returns (char *) -1 e.g. resource error.
The problem is that returning (char *) -1 will break all sorts of other
code, so while what we did is correct, the real failure case fix is
slightly broader.
There are 4 other places where _nl_find_msg is called, one is OK, the
other three are fixed to handle -1 error return value.
No regressions on x86-64 or x86.
However, no regressions isn't really a useful metric for this code.
The change was tested as documented here:
http://sourceware.org/glibc/wiki/Testing/WhiteBox
using SystemTap for fault injection to simulate malloc failure.
---
2013-05-03 Carlos O'Donell <carlos at redhat.com>
[BZ #15441]
* intl/dcigettext.c (DCIGETTEXT): Skip translating if _nl_find_msg
returns -1.
(_nl_find_msg): Return -1 if recursive call returned -1. If newmem is
null return -1.
* intl/loadmsgcat.c (_nl_load_domain): If _nl_find_msg returns -1 abort
loading the domain.
This commit is contained in:
parent
b50a71810b
commit
7a44c18fb4
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2013-05-03 Carlos O'Donell <carlos at redhat.com>
|
||||||
|
|
||||||
|
[BZ #15441]
|
||||||
|
* intl/dcigettext.c (DCIGETTEXT): Skip translating if _nl_find_msg
|
||||||
|
returns -1.
|
||||||
|
(_nl_find_msg): Return -1 if recursive call returned -1. If newmem is
|
||||||
|
null return -1.
|
||||||
|
* intl/loadmsgcat.c (_nl_load_domain): If _nl_find_msg returns -1 abort
|
||||||
|
loading the domain.
|
||||||
|
|
||||||
2013-05-22 Joseph Myers <joseph@codesourcery.com>
|
2013-05-22 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* math/gen-libm-test.pl (parse_args): Do not include expected
|
* math/gen-libm-test.pl (parse_args): Do not include expected
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -17,8 +17,8 @@ Version 2.18
|
||||||
15085, 15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287,
|
15085, 15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287,
|
||||||
15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15339,
|
15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15339,
|
||||||
15342, 15346, 15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406,
|
15342, 15346, 15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406,
|
||||||
15409, 15416, 15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448,
|
15409, 15416, 15418, 15419, 15423, 15424, 15426, 15429, 15441, 15442,
|
||||||
15480, 15485, 15488, 15490, 15493, 15497, 15506.
|
15448, 15480, 15485, 15488, 15490, 15493, 15497, 15506.
|
||||||
|
|
||||||
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
||||||
#15078).
|
#15078).
|
||||||
|
|
|
@ -638,6 +638,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
|
||||||
retval = _nl_find_msg (domain->successor[cnt], binding,
|
retval = _nl_find_msg (domain->successor[cnt], binding,
|
||||||
msgid1, 1, &retlen);
|
msgid1, 1, &retlen);
|
||||||
|
|
||||||
|
/* Resource problems are not fatal, instead we return no
|
||||||
|
translation. */
|
||||||
|
if (__builtin_expect (retval == (char *) -1, 0))
|
||||||
|
goto no_translation;
|
||||||
|
|
||||||
if (retval != NULL)
|
if (retval != NULL)
|
||||||
{
|
{
|
||||||
domain = domain->successor[cnt];
|
domain = domain->successor[cnt];
|
||||||
|
@ -941,6 +946,11 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
||||||
nullentry =
|
nullentry =
|
||||||
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
_nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||||
|
|
||||||
|
/* Resource problems are fatal. If we continue onwards we will
|
||||||
|
only attempt to calloc a new conv_tab and fail later. */
|
||||||
|
if (__builtin_expect (nullentry == (char *) -1, 0))
|
||||||
|
return (char *) -1;
|
||||||
|
|
||||||
if (nullentry != NULL)
|
if (nullentry != NULL)
|
||||||
{
|
{
|
||||||
const char *charsetstr;
|
const char *charsetstr;
|
||||||
|
@ -1170,10 +1180,14 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp)
|
||||||
freemem_size = INITIAL_BLOCK_SIZE;
|
freemem_size = INITIAL_BLOCK_SIZE;
|
||||||
newmem = (transmem_block_t *) malloc (freemem_size);
|
newmem = (transmem_block_t *) malloc (freemem_size);
|
||||||
# ifdef _LIBC
|
# ifdef _LIBC
|
||||||
|
if (newmem != NULL)
|
||||||
|
{
|
||||||
/* Add the block to the list of blocks we have to free
|
/* Add the block to the list of blocks we have to free
|
||||||
at some point. */
|
at some point. */
|
||||||
newmem->next = transmem_list;
|
newmem->next = transmem_list;
|
||||||
transmem_list = newmem;
|
transmem_list = newmem;
|
||||||
|
}
|
||||||
|
/* Fall through and return -1. */
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
if (__builtin_expect (newmem == NULL, 0))
|
if (__builtin_expect (newmem == NULL, 0))
|
||||||
|
|
|
@ -1237,7 +1237,7 @@ _nl_load_domain (domain_file, domainbinding)
|
||||||
default:
|
default:
|
||||||
/* This is an invalid revision. */
|
/* This is an invalid revision. */
|
||||||
invalid:
|
invalid:
|
||||||
/* This is an invalid .mo file. */
|
/* This is an invalid .mo file or we ran out of resources. */
|
||||||
free (domain->malloced);
|
free (domain->malloced);
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
if (use_mmap)
|
if (use_mmap)
|
||||||
|
@ -1257,6 +1257,11 @@ _nl_load_domain (domain_file, domainbinding)
|
||||||
|
|
||||||
/* Get the header entry and look for a plural specification. */
|
/* Get the header entry and look for a plural specification. */
|
||||||
nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
|
||||||
|
if (__builtin_expect (nullentry == (char *) -1, 0))
|
||||||
|
{
|
||||||
|
__libc_rwlock_fini (domain->conversions_lock);
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
|
EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue