php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79571 FFI: var_dumping unions may segfault
Submitted: 2020-05-07 06:01 UTC Modified: 2020-05-11 13:53 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: peratx at itxtech dot org Assigned: cmb (profile)
Status: Closed Package: *Extensibility Functions
PHP Version: 7.4.5 OS: Windows 10 1903
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: peratx at itxtech dot org
New email:
PHP Version: OS:

 

 [2020-05-07 06:01 UTC] peratx at itxtech dot org
Description:
------------
When accessing Windows LPSTR, the whole program crashes.

===========
php -v
PHP 7.3.8 (cli) (built: Jul 30 2019 12:44:06) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.8, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.8, Copyright (c) 1999-2018, by Zend Technologies

php -m
[PHP Modules]
bcmath
calendar
Core
ctype
curl
date
dom
filter
gd
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
Phar
pthreads
readline
Reflection
runkit7
session
SimpleXML
sockets
sodium
SPL
sqlite3
standard
tokenizer
wddx
xml
xmlreader
xmlwriter
yaml
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache


Test script:
---------------
$ffi = \FFI::cdef(<<<EOL
typedef unsigned long DWORD;
typedef int BOOL;
typedef DWORD *LPDWORD;
typedef void *LPVOID;
typedef LPVOID HINTERNET;
typedef char* *LPSTR;
typedef struct {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
typedef struct {
  DWORD dwOption;
  union {
    DWORD    dwValue;
    LPSTR    pszValue;
    FILETIME ftValue;
  } Value;
} INTERNET_PER_CONN_OPTIONA, *LPINTERNET_PER_CONN_OPTIONA;
typedef struct {
  DWORD                       dwSize;
  LPSTR                       pszConnection;
  DWORD                       dwOptionCount;
  DWORD                       dwOptionError;
  LPINTERNET_PER_CONN_OPTIONA pOptions;
} INTERNET_PER_CONN_OPTION_LISTA, *LPINTERNET_PER_CONN_OPTION_LISTA;
typedef DWORD WINAPI_InternetOption;
BOOL InternetSetOptionA(HINTERNET hInternet, WINAPI_InternetOption dwOption, LPVOID lpBuffer, DWORD dwBufferLength);
BOOL InternetQueryOptionA(HINTERNET hInternet, WINAPI_InternetOption dwOption, LPVOID lpBuffer, LPDWORD 
lpdwBufferLength);
EOL
			, "Wininet.dll");

$list = $ffi->new("INTERNET_PER_CONN_OPTION_LISTA");
		$opt = $ffi->new("INTERNET_PER_CONN_OPTIONA");
		$str = \FFI::new("char*", "");
		$opt->dwOption = 1;
		$opt->Value->pszValue = \FFI::addr($str);
		$list->dwSize = \FFI::sizeof($list);
		$list->pszConnection = null;
		$list->dwOptionCount = 1;
		$list->dwOptionError = 0;
		$list->pOptions = \FFI::addr($opt);
		$listptr = \FFI::addr($list);

		$int = $ffi->new("DWORD");
		$int->cdata = \FFI::sizeof($list) * 2;
		$ptr = \FFI::addr($int);

		$ffi->InternetQueryOptionA(null, 75, $listptr, $ptr);

		var_dump($list);// crashes when it comes to pszValue which is a LPSTR pointer

Expected result:
----------------
object(FFI\CData:struct <anonymous>)#5 (5) {
  ["dwSize"]=>
  int(32)
  ["pszConnection"]=>
  NULL
  ["dwOptionCount"]=>
  int(1)
  ["dwOptionError"]=>
  int(0)
  ["pOptions"]=>
  object(FFI\CData:struct <anonymous>*)#11 (1) {
    [0]=>
    object(FFI\CData:struct <anonymous>)#12 (2) {
      ["dwOption"]=>
      int(1)
      ["Value"]=>
      object(FFI\CData:union <anonymous>)#13 (3) {
        ["dwValue"]=>
        int(2)
        ["pszValue"]=>
        string(xxx) "xxxxx"
        ["value...."]

Actual result:
--------------
object(FFI\CData:struct <anonymous>)#5 (5) {
  ["dwSize"]=>
  int(32)
  ["pszConnection"]=>
  NULL
  ["dwOptionCount"]=>
  int(1)
  ["dwOptionError"]=>
  int(0)
  ["pOptions"]=>
  object(FFI\CData:struct <anonymous>*)#11 (1) {
    [0]=>
    object(FFI\CData:struct <anonymous>)#12 (2) {
      ["dwOption"]=>
      int(1)
      ["Value"]=>
      object(FFI\CData:union <anonymous>)#13 (3) {
        ["dwValue"]=>
        int(2)
        ["pszValue"]=> //crashes

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-05-07 06:11 UTC] peratx at itxtech dot org
Wrong php info, it should be:
PHP 7.4.5 (cli) (built: Apr 14 2020 16:17:34) ( ZTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.5, Copyright (c), by Zend Technologie

[PHP Modules]
bcmath
calendar
Core
ctype
curl
date
dom
FFI
filter
gd
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
Phar
readline
Reflection
runkit7
session
SimpleXML
sockets
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
yaml
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache
 [2020-05-07 10:07 UTC] cmb@php.net
Simpler reproducer:

<?php
$ffi = FFI::cdef('
typedef union {
    int num;
    char *str;
} my_union;
');

$union = $ffi->new('my_union');
$union->num = 17;
var_dump($union);
?>

The problem is that FFI can't know which member of the union is
actually valid, but assumes that all are.
 [2020-05-07 10:09 UTC] cmb@php.net
-Summary: FFI: calling Win32 LPSTR crashes +Summary: FFI: var_dumping unions may segfault
 [2020-05-07 10:39 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79571: FFI: var_dumping unions may segfault
On GitHub:  https://github.com/php/php-src/pull/5538
Patch:      https://github.com/php/php-src/pull/5538.patch
 [2020-05-07 12:33 UTC] peratx at itxtech dot org
Maybe this issue is related to C Union.
 [2020-05-11 13:52 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79571: FFI: var_dumping unions may segfault
On GitHub:  https://github.com/php/php-src/pull/5544
Patch:      https://github.com/php/php-src/pull/5544.patch
 [2020-05-11 13:53 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2020-05-11 14:26 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=d5300873c5a8a02cff0215327a0b8c730ec9de42
Log: Fix #79571: FFI: var_dumping unions may segfault
 [2020-05-11 14:26 UTC] cmb@php.net
-Status: Verified +Status: Closed
 [2020-05-11 14:26 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=d5300873c5a8a02cff0215327a0b8c730ec9de42
Log: Fix #79571: FFI: var_dumping unions may segfault
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Nov 26 16:01:23 2020 UTC