php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69971 Use-after-free in sqlite3 when destroying statement object
Submitted: 2015-06-30 15:17 UTC Modified: 2019-01-21 13:49 UTC
From: s dot paraschoudis at gmail dot com Assigned: cmb (profile)
Status: Duplicate Package: SQLite related
PHP Version: 5.6.10 OS: Ubuntu 14.04.1 LTS (32 bit)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: s dot paraschoudis at gmail dot com
New email:
PHP Version: OS:

 

 [2015-06-30 15:17 UTC] s dot paraschoudis at gmail dot com
Description:
------------
PoC
==============
<?php
$conn = new sqlite3(':memory:');
$conn->query('CREATE TABLE users (id INTEGER NOT NULL, PRIMARY KEY(id))');
$stmt = $conn->prepare('insert into users (id) values (:id)') +
$stmt->execute();
?>

Running the following PoC we get:

user@ubuntuvm:~/Desktop$ USE_ZEND_ALLOC=0 ~/Desktop/php-5.6.10/sapi/cli/php zend_llist_del_element_uaf.php

Notice: Undefined variable: stmt in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5
PHP Fatal error:  Call to a member function execute() on null in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5
=================================================================
==3455== ERROR: AddressSanitizer: heap-use-after-free on address 0xb521d0e4 at pc 0x8aac792 bp 0xbfe425d8 sp 0xbfe425cc
READ of size 4 at 0xb521d0e4 thread T0
    #0 0x8aac791 in zend_llist_del_element zend_llist.c:93
    #1 0x821d4e5 in php_sqlite3_stmt_object_free_storage sqlite3.c:2138
    #2 0x8b88c26 in zend_objects_store_free_object_storage zend_objects_API.c:97
    #3 0x8a9e392 in shutdown_executor zend_execute_API.c:290
    #4 0x8adbb54 in zend_deactivate zend.c:960
    #5 0x894a998 in php_request_shutdown main.c:1883
    #6 0x8d15e80 in do_cli php_cli.c:1177
    #7 0x8d172c0 in main php_cli.c:1378
    #8 0xb5dd5a82 in __libc_start_main libc-start.c:287
    #9 0x80628b0 in _start ??:?
0xb521d0e4 is located 36 bytes inside of 64-byte region [0xb521d0c0,0xb521d100)
freed by thread T0 here:
    #0 0xb617b774 in __interceptor_free ??:?
    #1 0x8a2de51 in _efree zend_alloc.c:2437
    #2 0x821d306 in php_sqlite3_object_free_storage sqlite3.c:2119
    #3 0x8b88c26 in zend_objects_store_free_object_storage zend_objects_API.c:97
    #4 0x8a9e392 in shutdown_executor zend_execute_API.c:290
    #5 0x8adbb54 in zend_deactivate zend.c:960
    #6 0x894a998 in php_request_shutdown main.c:1883
    #7 0x8d15e80 in do_cli php_cli.c:1177
    #8 0x8d172c0 in main php_cli.c:1378
    #9 0xb5dd5a82 in __libc_start_main libc-start.c:287
previously allocated by thread T0 here:
    #0 0xb617b854 in malloc ??:?
    #1 0x8a2dd20 in _emalloc zend_alloc.c:2427
    #2 0x821d8ce in php_sqlite3_object_new sqlite3.c:2183
    #3 0x8ae97e7 in _object_and_properties_init zend_API.c:1199
    #4 0x8ae984a in _object_init_ex zend_API.c:1207
    #5 0x8ba4383 in ZEND_NEW_SPEC_HANDLER zend_vm_execute.h:945
    #6 0x8b9d3d9 in execute_ex zend_vm_execute.h:363
    #7 0x8b9d4e4 in zend_execute zend_vm_execute.h:388
    #8 0x8ade628 in zend_execute_scripts zend.c:1341
    #9 0x894d95b in php_execute_script main.c:2597
    #10 0x8d14b83 in do_cli php_cli.c:994
    #11 0x8d172c0 in main php_cli.c:1378
    #12 0xb5dd5a82 in __libc_start_main libc-start.c:287
==3455== ABORTING

Running it under gdb:

gdb-peda$ r zend_llist_del_element_uaf.php 
Starting program: /home/user/Desktop/php5610/sapi/cli/php zend_llist_del_element_uaf.php
PHP Notice:  Undefined variable: stmt in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5

Notice: Undefined variable: stmt in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5
PHP Fatal error:  Call to a member function execute() on null in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5

Fatal error: Call to a member function execute() on null in /home/user/Desktop/zend_llist_del_element_uaf.php on line 5

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x5a5a5a62 ('bZZZ')
EBX: 0x8000000 
ECX: 0x38 ('8')
EDX: 0x5a5a5a62 ('bZZZ')
ESI: 0x0 
EDI: 0x89bf1d8 --> 0x0 
EBP: 0xbfffda58 --> 0xbfffda98 --> 0xbfffdad8 --> 0xbfffdb08 --> 0xbfffdbf8 --> 0xbfffdcc8 --> 0xbfffddb8 --> 0xbfffefa8 --> 0xbffff0c8 --> 0x0 
ESP: 0xbfffda58 --> 0xbfffda98 --> 0xbfffdad8 --> 0xbfffdb08 --> 0xbfffdbf8 --> 0xbfffdcc8 --> 0xbfffddb8 --> 0xbfffefa8 --> 0xbffff0c8 --> 0x0 
EIP: 0x8110282 (<php_sqlite3_compare_stmt_free+6>:  mov    eax,DWORD PTR [eax])
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x811027c <php_sqlite3_compare_stmt_free>: push   ebp
   0x811027d <php_sqlite3_compare_stmt_free+1>: mov    ebp,esp
   0x811027f <php_sqlite3_compare_stmt_free+3>: mov    eax,DWORD PTR [ebp+0x8]
=> 0x8110282 <php_sqlite3_compare_stmt_free+6>: mov    eax,DWORD PTR [eax]
   0x8110284 <php_sqlite3_compare_stmt_free+8>: mov    eax,DWORD PTR [eax+0x4]
   0x8110287 <php_sqlite3_compare_stmt_free+11>:  mov    eax,DWORD PTR [eax+0x1c]
   0x811028a <php_sqlite3_compare_stmt_free+14>:  test   eax,eax
   0x811028c <php_sqlite3_compare_stmt_free+16>:  je     0x81102a5 <php_sqlite3_compare_stmt_free+41>
[------------------------------------stack-------------------------------------]
0000| 0xbfffda58 --> 0xbfffda98 --> 0xbfffdad8 --> 0xbfffdb08 --> 0xbfffdbf8 --> 0xbfffdcc8 --> 0xbfffddb8 --> 0xbfffefa8 --> 0xbffff0c8 --> 0x0 
0004| 0xbfffda5c --> 0x841944e (<zend_llist_del_element+40>:  test   eax,eax)
0008| 0xbfffda60 ("bZZZ\330Ū\b\230\332\377\277\254\231?\b\360\361\233\bx\367\275\267\260\231Z\bG\b")
0012| 0xbfffda64 --> 0x8aac5d8 --> 0x8a9b188 --> 0x899e780 --> 0x3 
0016| 0xbfffda68 --> 0xbfffda98 --> 0xbfffdad8 --> 0xbfffdb08 --> 0xbfffdbf8 --> 0xbfffdcc8 --> 0xbfffddb8 --> 0xbfffefa8 --> 0xbffff0c8 --> 0x0 
0020| 0xbfffda6c --> 0x83f99ac (<_efree+91>:  leave)
0024| 0xbfffda70 --> 0x89bf1f0 --> 0x1 
0028| 0xbfffda74 --> 0xb7bdf778 ('Z' <repeats 64 times>, "\204\243\034\263\364ZWh=")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x08110282 in php_sqlite3_compare_stmt_free (free_list=0x5a5a5a62, statement=0x8aac5d8) at /home/user/Desktop/php5610/ext/sqlite3/sqlite3.c:2065
2065    return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);

gdb-peda$ print free_list
$1 = (php_sqlite3_free_list **) 0x5a5a5a62

gdb-peda$ print *free_list
Cannot access memory at address 0x5a5a5a62

gdb-peda$ ptype free_list
type = struct _php_sqlite3_free_list {
    zval *stmt_obj_zval;
    php_sqlite3_stmt *stmt_obj;
} **

As seen above, both EAX and EDX point to freed memory.

Regards,
Symeon.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-07-05 04:25 UTC] stas@php.net
-Assigned To: +Assigned To: scottmac
 [2015-07-05 04:25 UTC] stas@php.net
Looks like this happens because php_sqlite3_db_object is destroyed before php_sqlite3_stmt by shutdown handler, but stmt object tries to access intern->db_obj->free_list, which is in memory already freed when destroying db_object. I'd advise SQL maintainer to take a look, though it doesn't look like a security issue.
 [2015-07-05 04:26 UTC] stas@php.net
-Summary: Use-after-free vulnerability in zend_llist_del_element() +Summary: Use-after-free in sqlite3 when destroying statement object
 [2015-07-05 04:26 UTC] stas@php.net
-Type: Security +Type: Bug
 [2017-10-24 06:10 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: scottmac +Assigned To:
 [2018-10-15 22:36 UTC] cmb@php.net
-Package: Reproducible crash +Package: SQLite related
 [2018-10-15 22:36 UTC] cmb@php.net
On a quick glance this looks like a duplicate of bug #53626.
Therefore I'm changing the package to “SQLite related” to better
track the issue.
 [2019-01-21 13:49 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2019-01-21 13:49 UTC] cmb@php.net
Indeed, this is a duplicate of bug #53626.  Since that ticket
isn't private, I'm publishing this one.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Nov 25 21:01:33 2024 UTC