|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-01-12 22:53 UTC] dominic at varspool dot com
Description: ------------ When calling finfo::file() or finfo::buffer() with a crafted string, PHP will crash by either segfaulting or trying to allocate an large amount of memory (4GiB). This was found in the wild when a user uploaded a file (running finfo on arbitrary files uploaded by users is one of its main use cases.). I've since anonymised the file, and made it more minimal. At this stage, very small changes to the string make it produce different behaviour - removing the remaining 'a', 's', or 'y' characters, for instance, will allow finfo to process it fine. I suspect a bad magic rule (but I can't tell which from gdb). Test script: --------------- The basic test script is: <?php $string = <magic value> $finfo = new finfo(); $type = $finfo->buffer($string); var_dump($type); ?> Here are 3v4l links to versions of the magic value that cause unexpected behaviour: Spurious OOM error (tried to allocate 4GB): http://3v4l.org/gOeJ3 Segfault: http://3v4l.org/HghCY The difference in the strings in the two versions is an single '-' before the first CRLF linebreak. The behaviour is the same when the string is written to a file and loaded with finfo::file(). Expected result: ---------------- string(60) "ASCII text, with very long lines, with CRLF line terminators" Actual result: -------------- With one string: Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 4294967295 bytes) in <script> on line X With a very slightly different string: Segmentation fault Here's the backtrace: #0 __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:36 #1 0x00000000007ce518 in _estrndup ( s=0x7f692d976071 "-------a", '-' <repeats 12 times>, "s-----''------a----s--------a", '-' <repeats 13 times>, "a-\r\n", length=4294967295, __zend_filename=0xbfd968 "/home/someone/php-5.6.4/ext/fileinfo/libmagic/softmagic.c", __zend_lineno=2108, __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/someone/php-5.6.4/Zend/zend_alloc.c:2655 #2 0x00000000005c3ebf in magiccheck (ms=0x7f692db41978, m=0xbbb460 <php_magic_database+2544480>) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/softmagic.c:2108 #3 0x00000000005bf080 in match (ms=0x7f692db41978, magic=0x94e1f8 <php_magic_database+248>, nmagic=10428, s=0x7f692d974070 "----a-----'''---------a", '-' <repeats 15 times>, "a--------a-----a-----a---------a-----as-------a----a--a", '-' <repeats 13 times>, "a--as-----s", '-' <repeats 15 times>, "a---------a---a--s-a-----a", '-' <repeats 11 times>, "asy---------a-----a", '-' <repeats 11 times>, "a"..., nbytes=8259, offset=0, mode=64, text=1, flip=0, recursion_level=0, printed_something=0x7fff3a875c5c, need_separator=0x7fff3a875c60, returnval=0x7fff3a875bac) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/softmagic.c:274 #4 0x00000000005beae0 in file_softmagic (ms=0x7f692db41978, buf=0x7f692d974070 "----a-----'''---------a", '-' <repeats 15 times>, "a--------a-----a-----a---------a-----as-------a----a--a", '-' <repeats 13 times>, "a--as-----s", '-' <repeats 15 times>, "a---------a---a--s-a-----a", '-' <repeats 11 times>, "asy---------a-----a", '-' <repeats 11 times>, "a"..., nbytes=8259, level=0, mode=64, text=1) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/softmagic.c:93 #5 0x00000000005b6414 in file_ascmagic_with_encoding (ms=0x7f692db41978, buf=0x7f692da28dc0 "----a-----'''---------a", '-' <repeats 15 times>, "a--------a-----a-----a---------a-----as-------a----a--a", '-' <repeats 13 times>, "a--as-----s", '-' <repeats 15 times>, "a---------a---a--s-a-----a", '-' <repeats 11 times>, "asy---------a-----a", '-' <repeats 11 times>, "a"..., nbytes=8259, ubuf=0x2d37a60, ulen=8259, code=0xbfcdd3 "ASCII", type=0xbfcdbf "text", text=1) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/ascmagic.c:149 #6 0x00000000005b6230 in file_ascmagic (ms=0x7f692db41978, buf=0x7f692da28dc0 "----a-----'''---------a", '-' <repeats 15 times>, "a--------a-----a-----a---------a-----as-------a----a--a", '-' <repeats 13 times>, "a--as-----s", '-' <repeats 15 times>, "a---------a---a--s-a-----a", '-' <repeats 11 times>, "asy---------a-----a", '-' <repeats 11 times>, "a"..., nbytes=8259, text=1) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/ascmagic.c:92 #7 0x00000000005bc45e in file_buffer (ms=0x7f692db41978, stream=0x0, inname=0x0, buf=0x7f692da28dc0, nb=8259) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/funcs.c:264 #8 0x00000000005bd62c in magic_buffer (ms=0x7f692db41978, buf=0x7f692da28dc0, nb=8259) at /home/someone/php-5.6.4/ext/fileinfo/libmagic/magic.c:435 #9 0x00000000005af439 in _php_finfo_get_type (ht=1, return_value=0x7f692db3f320, return_value_ptr=0x7f692db07210, this_ptr=0x7f692db3cc20, return_value_used=1, mode=0, mimetype_emu=0) at /home/someone/php-5.6.4/ext/fileinfo/fileinfo.c:476 #10 0x00000000005af9a2 in zif_finfo_buffer (ht=1, return_value=0x7f692db3f320, return_value_ptr=0x7f692db07210, this_ptr=0x7f692db3cc20, return_value_used=1) at /home/someone/php-5.6.4/ext/fileinfo/fileinfo.c:588 #11 0x000000000084c4a7 in zend_do_fcall_common_helper_SPEC (execute_data=0x7f692db072e8) at /home/someone/php-5.6.4/Zend/zend_vm_execute.h:558 #12 0x000000000084cc7e in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7f692db072e8) at /home/someone/php-5.6.4/Zend/zend_vm_execute.h:693 #13 0x000000000084bb16 in execute_ex (execute_data=0x7f692db072e8) at /home/someone/php-5.6.4/Zend/zend_vm_execute.h:363 #14 0x000000000084bb9f in zend_execute (op_array=0x7f692db3dbb8) at /home/someone/php-5.6.4/Zend/zend_vm_execute.h:388 #15 0x00000000008079c8 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/someone/php-5.6.4/Zend/zend.c:1344 #16 0x000000000076e291 in php_execute_script (primary_file=0x7fff3a8786c0) at /home/someone/php-5.6.4/main/main.c:2584 #17 0x00000000008b9f9d in do_cli (argc=2, argv=0x2ba9bd0) at /home/someone/php-5.6.4/sapi/cli/php_cli.c:994 #18 0x00000000008bb2cb in main (argc=2, argv=0x2ba9bd0) at /home/someone/php-5.6.4/sapi/cli/php_cli.c:1378 Patchesbug68819 (last revision 2015-03-02 13:23 UTC by ab@php.net)bug68819_56.patch (last revision 2015-02-05 15:56 UTC by ab@php.net) bug68819_54.patch (last revision 2015-02-05 15:55 UTC by ab@php.net) Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 21:00:01 2025 UTC |
I'd give feedback, but the patches are private for me ("You have no access to bug #68819"). (I'm using the password from the original bug submission to do edits like this.)On master, I applied the 5.6/master patch, and confirmed the test cases now pass. However, I can still target other rules. Here's another one: <?php $string = 'try: except:'; $string .= str_repeat(' ', 8178); $string .= 'say'; var_dump(strlen($string)); $finfo = new finfo(); $type = $finfo->buffer($string); var_dump($type); ?> I crafted this one to target the rule: 0 search/4096 try: >&0 regex \^\\s*except.*: Python script text executable (This from just grepping for search/4096 followed by a regex continuation).Ok, i've two news ... :) For one - the same overflow behavior is to reproduce in file-5.22, that means - it's not a PHP issue, but the mainstream one. Decide which one is bad/good. This bug is present in at least the range of 5.19-5.22. To reproduce, use the data from your latest PHP snippet and set a breakpoint like this (in 5.22): (gdb) b softmagic.c:1140 if buf > last I've also checked the current libmagic master, and there the issue isn't present anymore. However the code base differs now far more (not even talking that it's not released yet), so i would not backport it. Instead, i'd probably a hotfix for our codebase. We might still try to backport something later after the current master (probably 5.23) is released, right now I'd rather ensure that the offset doesn't exceed bytecnt or vice versa. That is the key point. On 5.6, please try the following patch: ====== START ======= diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index c8c72b2..0938ea6 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -1074,6 +1074,9 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, if (bytecnt > nbytes) { bytecnt = nbytes; } + if (offset > bytecnt) { + offset = bytecnt; + } if (s == NULL) { ms->search.s_len = 0; ms->search.s = NULL; ====== END ======= With this, it should be working even without the data patch. While the data patch can be updated later. Thanks.