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
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: 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

Pull Requests

Pull requests:

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC