php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #67397 Buffer overflow in locale_get_display_name->uloc_getDisplayName (libicu 4.8.1)
Submitted: 2014-06-08 10:39 UTC Modified: 2014-06-27 23:16 UTC
From: mikispag at gmail dot com Assigned: stas
Status: Closed Package: Unicode Engine related
PHP Version: 5.5.13 OS: Linux
Private report: No CVE-ID:
 [2014-06-08 10:39 UTC] mikispag at gmail dot com
Description:
------------
// Any string > 255 characters passed as the first parameter of locale_get_display_name
// will cause a buffer overflow in ICU library (libicuuc.so)
// 
// #0  0x00007ffff3d0c425 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
// #1  0x00007ffff3d0fb8b in __GI_abort () at abort.c:91
// #2  0x00007ffff3d4a39e in __libc_message (do_abort=2, fmt=0x7ffff3e5257f "*** %s ***: %s terminated\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:201
// #3  0x00007ffff3de0f47 in __GI___fortify_fail (msg=0x7ffff3e52567 "stack smashing detected") at fortify_fail.c:32
// #4  0x00007ffff3de0f10 in __stack_chk_fail () at stack_chk_fail.c:29
// #5  0x00007ffff4accdac in ures_getByKeyWithFallback_48 () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #6  0x00007ffff4acce03 in ures_getStringByKeyWithFallback_48 () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #7  0x00007ffff4adda09 in uloc_getTableStringWithFallback_48 () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #8  0x00007ffff4adae1b in ?? () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #9  0x00007ffff4adb037 in ?? () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #10 0x00007ffff4adb0bb in uloc_getDisplayLanguage_48 () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #11 0x00007ffff4adbf45 in uloc_getDisplayName_48 () from /usr/lib/x86_64-linux-gnu/libicuuc.so.48
// #12 0x00000000007041d2 in get_icu_disp_value_src_php (tag_name=0xef83ad "name", ht=1, return_value=0x7ffff7fb2140, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
//     at /tmp/php-5.5.12/ext/intl/locale/locale_methods.c:542
// #13 0x00000000007044c0 in zif_locale_get_display_name (ht=1, return_value=0x7ffff7fb2140, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
//     at /tmp/php-5.5.12/ext/intl/locale/locale_methods.c:602
// #14 0x0000000000b36b2f in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7f7a168) at /tmp/php-5.5.12/Zend/zend_vm_execute.h:550
// #15 0x0000000000b3b367 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7ffff7f7a168) at /tmp/php-5.5.12/Zend/zend_vm_execute.h:2329
// #16 0x0000000000b3623d in execute_ex (execute_data=0x7ffff7f7a168) at /tmp/php-5.5.12/Zend/zend_vm_execute.h:363
// #17 0x0000000000b362c2 in zend_execute (op_array=0x7ffff7fb3048) at /tmp/php-5.5.12/Zend/zend_vm_execute.h:388
// #18 0x0000000000af6d7d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /tmp/php-5.5.12/Zend/zend.c:1316
// #19 0x0000000000a5ecbd in php_execute_script (primary_file=0x7fffffffd090) at /tmp/php-5.5.12/main/main.c:2506
// #20 0x0000000000ba453f in do_cli (argc=2, argv=0x14141d0) at /tmp/php-5.5.12/sapi/cli/php_cli.c:994
// #21 0x0000000000ba57d4 in main (argc=2, argv=0x14141d0) at /tmp/php-5.5.12/sapi/cli/php_cli.c:1378

Test script:
---------------
locale_get_display_name(str_repeat('*', 256));


Patches

bug67397-patch (last revision 2014-06-08 20:45 UTC) by stas@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-08 10:40 UTC] mikispag at gmail dot com
U_CAPI UResourceBundle* U_EXPORT2 
ures_getByKeyWithFallback(const UResourceBundle *resB, 
                          const char* inKey, 
                          UResourceBundle *fillIn, 
                          UErrorCode *status) {
...
char path[256];
...
                    if (len > 0) {
                        uprv_memcpy(path, resPath, len);
                    }
                    uprv_strcpy(path+len, inKey); // inKey is user-supplied so that will end badly ...
...

Here is a trivial PoC that will trigger the bug:

-------------------------------------------------------------------------------------------------------------------
#include "unicode/utypes.h"
#include "unicode/uenum.h"
#define RESLEN 512

// COMPILE WITH:
// gcc -o funicu funicu.c `pkg-config --libs --cflags icu-uc icu-i18n icu-le icu-lx icu-io`

int main(void)
{
char locale[512];
UChar *result;
UErrorCode *err;
int32_t rc;
int i;

	result = malloc(RESLEN);
	err = malloc(sizeof(UErrorCode));
	memset(locale, '*', sizeof(locale));
	locale[ sizeof(locale)-1 ] = '\x00';

	rc = uloc_getDisplayName( locale,	// const localeID
		"en_US",		// const inLocaleID
		result,			// result
		RESLEN,			// maxresultSize
		err
	);

	return 0;
}
-------------------------------------------------------------------------------------------------------------------

ures_getByKeyWithFallback() is an internal function used by many others, including but not limited to uloc_getDisplayName().

I have already reported this to libicu developers.
 [2014-06-08 20:30 UTC] stas@php.net
Not sure if we can fix this in PHP. From the code it looks like they are appending inKey to existing resource path and putting this in a buffer 256 bytes long. However, without knowing how bug resource path is, we can not know what is the safe length for inKey. We could limit inKey by 128 chars, but nothing guarantees it can't be overflown. Maybe ULOC_FULLNAME_CAPACITY would be a good margin, but again I see no guarantees.
 [2014-06-08 20:45 UTC] stas@php.net
The following patch has been added/updated:

Patch Name: bug67397-patch
Revision:   1402260338
URL:        https://bugs.php.net/patch-display.php?bug=67397&patch=bug67397-patch&revision=1402260338
 [2014-06-14 17:01 UTC] mikispag at gmail dot com
HHVM patched with this commit: https://github.com/facebook/hhvm/commit/4e48132b27ec67ca0425e5d90d3863cab4d209f2

(if this can be useful)
 [2014-06-14 19:03 UTC] stas@php.net
HHVM patch may not go far enough - the buffer there is 256, and they are adding stuff to the original string, so 255 may still break things. ULOC_FULLNAME_CAPACITY is 157 which seems to give it some space.
 [2014-06-27 23:16 UTC] stas@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: stas
 [2014-06-27 23:16 UTC] stas@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2a29add9e41cf98eb516be6bafd66a13cb42b9b3
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f48b8f33393742b2c4adc6ec91127c7f228618e4
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-06-30 20:23 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 01:41 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f48b8f33393742b2c4adc6ec91127c7f228618e4
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 01:41 UTC] tyrael@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 08:26 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f48b8f33393742b2c4adc6ec91127c7f228618e4
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 08:26 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2a29add9e41cf98eb516be6bafd66a13cb42b9b3
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f48b8f33393742b2c4adc6ec91127c7f228618e4
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-02 08:33 UTC] ab@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-07-29 21:56 UTC] johannes@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e644aad3f9138bbb2e77520f033ba902f236b8b5
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-08-14 15:34 UTC] johannes@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e644aad3f9138bbb2e77520f033ba902f236b8b5
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-08-14 19:32 UTC] dmitry@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=e644aad3f9138bbb2e77520f033ba902f236b8b5
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-10-07 23:13 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=e644aad3f9138bbb2e77520f033ba902f236b8b5
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-10-07 23:14 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-10-07 23:25 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=e644aad3f9138bbb2e77520f033ba902f236b8b5
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2014-10-07 23:25 UTC] stas@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=6027c56fd727d2c4b193b96fee19cdbb4a128447
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 [2016-07-20 11:40 UTC] davey@php.net
Automatic comment on behalf of stas
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2a29add9e41cf98eb516be6bafd66a13cb42b9b3
Log: Fix bug #67397 (Buffer overflow in locale_get_display_name-&gt;uloc_getDisplayName (libicu 4.8.1))
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC