php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71683 Null pointer dereference in zend_hash_str_find_bucket
Submitted: 2016-02-28 15:02 UTC Modified: 2016-03-11 23:20 UTC
From: dmoorefo at gmail dot com Assigned: yohgaki (profile)
Status: Closed Package: Reproducible crash
PHP Version: 7.0.3 OS: Ubuntu 14.04.1 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: dmoorefo at gmail dot com
New email:
PHP Version: OS:

 

 [2016-02-28 15:02 UTC] dmoorefo at gmail dot com
Description:
------------
A crafted ini file will cause a null pointer dereference leading to a segfault: 

; crash.ini
session.auto_start=1
session.use_only_cookies=

It appears that setting session.auto_start makes php run as if in a web server context yet it is running as a command line program. When REQUEST_URI is checked from the http globals, zend_hash_str_find_bucket is called with a null hash table. This causes a 4 byte invalid read at 0x10.

 
From ext/session/session.c:1613:

if (PS(define_sid) && !PS(id) &&
    (data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]),
    "REQUEST_URI", sizeof("REQUEST_URI") - 1)) &&Z_TYPE_P(data) == IS_STRING &&
    (p = strstr(Z_STRVAL_P(data), PS(session_name))) && p[lensess] == '='

I could not reproduce this with PHP 5.6.18.


Test script:
---------------
Compile 7.0.3 with ./configure and make.

# python -c "print 'session.auto_start=1\nsession.use_only_cookies='" > crash.ini
# ./sapi/cli/php -c crash.ini -r ''
Segmentation fault
#

# uname -a
Linux x-Acer 3.19.0-33-generic #38~14.04.1-Ubuntu SMP Fri Nov 6 18:17:49 UTC 2015 i686 i686 i686 GNU/Linux

Expected result:
----------------
No segfault.

Actual result:
--------------
==30268== Memcheck, a memory error detector
==30268== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30268== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==30268== Command: php -c min-000000 -r 
==30268== 
==30268== Invalid read of size 4
==30268==    at 0x8450C37: zend_hash_str_find_bucket (zend_hash.c:515)
==30268==    by 0x8450C37: zend_hash_str_find (zend_hash.c:1959)
==30268==    by 0x829756B: php_session_start (session.c:1613)
==30268==    by 0x829B366: php_rinit_session (session.c:2624)
==30268==    by 0x829B385: zm_activate_session (session.c:2632)
==30268==    by 0x8438058: zend_activate_modules (zend_API.c:2536)
==30268==    by 0x83A06DF: php_request_startup (main.c:1626)
==30268==    by 0x8553892: do_cli (php_cli.c:945)
==30268==    by 0x8554A4C: main (php_cli.c:1345)
==30268==  Address 0x10 is not stack'd, malloc'd or (recently) free'd


(gdb) bt
#0  0x08450c37 in zend_hash_str_find_bucket (h=0x8e64879d, len=0xb, str=0x895d637 "REQUEST_URI", 
    ht=0x0) at /root/php-7.0.3/Zend/zend_hash.c:515
#1  zend_hash_str_find (ht=0x0, str=0x895d637 "REQUEST_URI", len=0xb)
    at /root/php-7.0.3/Zend/zend_hash.c:1959
#2  0x0829756c in php_session_start () at /root/php-7.0.3/ext/session/session.c:1613
#3  0x0829b367 in php_rinit_session (auto_start=0x1) at /root/php-7.0.3/ext/session/session.c:2624
#4  0x0829b386 in zm_activate_session (type=0x1, module_number=0x13)
    at /root/php-7.0.3/ext/session/session.c:2632
#5  0x08438059 in zend_activate_modules () at /root/php-7.0.3/Zend/zend_API.c:2536
#6  0x083a06e0 in php_request_startup () at /root/php-7.0.3/main/main.c:1626
#7  0x08553893 in do_cli (argc=0x3, argv=0x8a67fb0) at /root/php-7.0.3/sapi/cli/php_cli.c:945
#8  0x08554a4d in main (argc=0x3, argv=0x8a67fb0) at /root/php-7.0.3/sapi/cli/php_cli.c:1345
(gdb) i r
eax            0x0	0x0
ecx            0x8e648754	0x8e648754
edx            0x895d642	0x895d642
ebx            0x8e64879d	0x8e64879d
esp            0xbfffdb50	0xbfffdb50
ebp            0xbfffdba8	0xbfffdba8
esi            0x0	0x0
edi            0x8a681f8	0x8a681f8
eip            0x8450c37	0x8450c37 <zend_hash_str_find+503>
eflags         0x10282	[ SF IF RF ]
cs             0x73	0x73
ss             0x7b	0x7b
ds             0x7b	0x7b
es             0x7b	0x7b
fs             0x0	0x0
gs             0x33	0x33
 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-01 15:39 UTC] johannes@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: yohgaki
 [2016-03-01 15:39 UTC] johannes@php.net
Assigning to yohgaki who works on session things. I don't think this is a security bug - if you can run PHP from CLI and use a custom ini you have full power already.
 [2016-03-01 18:58 UTC] yohgaki@php.net
Ack
 [2016-03-01 19:07 UTC] yohgaki@php.net
-Status: Assigned +Status: Analyzed
 [2016-03-01 19:07 UTC] yohgaki@php.net
Offending line should be 

(data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI") - 1))

IIRC, $_SERVER is jit global and it is not initialized here. I'll prepare patch soon, but I need to check code if initializing array is better or not.
 [2016-03-09 10:14 UTC] yohgaki@php.net
This is patch fixes the crash.

diff --git a/ext/session/session.c b/ext/session/session.c
index 994d762..d0ee626 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1611,6 +1611,7 @@ PHPAPI void php_session_start(void) /* {{{ */
 		 * '<session-name>=<session-id>' to allow URLs of the form
 		 * http://yoursite/<session-name>=<session-id>/script.php */
 		if (PS(define_sid) && !PS(id) &&
+			zend_is_auto_global_str("_SERVER", sizeof("_SERVER")-1) == SUCCESS &&
 			(data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI") - 1)) &&
 			Z_TYPE_P(data) == IS_STRING &&
 			(p = strstr(Z_STRVAL_P(data), PS(session_name))) &&

As I commented earlier, it was jit global issue.
We may fix this as a reliability issue which is a part of security property, but I don't think this crash is exploitable, is this?
 [2016-03-09 20:09 UTC] dmoorefo at gmail dot com
Agreed - the exploitability of this is extremely low and it should be reclassified as a reliability issue.

I have verified that the patch fixes the issue in 7.0.3 and 7.0.4.
 [2016-03-09 22:42 UTC] stas@php.net
-Type: Security +Type: Bug
 [2016-03-09 22:42 UTC] stas@php.net
Does not look like security issue. It's CLI and requires special settings which are extremely uncommon for CLI.
 [2016-03-11 01:33 UTC] yohgaki@php.net
OK. I'll just merge the fix to branches.
 [2016-03-11 23:19 UTC] yohgaki@php.net
Related to #71754
The fix committed for #71754 breaks transid. Correct patch will be committed soon.
 [2016-03-11 23:20 UTC] yohgaki@php.net
Related to Bug #71754
 [2016-03-11 23:34 UTC] yohgaki@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50fca7a02a6dff553b0b8cfbb8bfba39c88fb6ae
Log: Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket
 [2016-03-11 23:34 UTC] yohgaki@php.net
-Status: Analyzed +Status: Closed
 [2016-03-11 23:43 UTC] yohgaki@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ca61f5954bf9e64072bfa31b4a7431e211a109e7
Log: Fixed Bug #71754 Regression in PHP7.0: trivial script segfaults php-cgi Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket Fixed Bug #71599 trans sid handling rework broke interaction with cookies
 [2016-03-11 23:43 UTC] yohgaki@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50fca7a02a6dff553b0b8cfbb8bfba39c88fb6ae
Log: Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket
 [2016-03-14 14:59 UTC] ab@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ca61f5954bf9e64072bfa31b4a7431e211a109e7
Log: Fixed Bug #71754 Regression in PHP7.0: trivial script segfaults php-cgi Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket Fixed Bug #71599 trans sid handling rework broke interaction with cookies
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ca61f5954bf9e64072bfa31b4a7431e211a109e7
Log: Fixed Bug #71754 Regression in PHP7.0: trivial script segfaults php-cgi Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket Fixed Bug #71599 trans sid handling rework broke interaction with cookies
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of yohgaki
Revision: http://git.php.net/?p=php-src.git;a=commit;h=50fca7a02a6dff553b0b8cfbb8bfba39c88fb6ae
Log: Fixed Bug #71683 Null pointer dereference in zend_hash_str_find_bucket
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC