php / php/php-src

FFI\CData use-after-free after FFI object destroyed

オープン
#8,556 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Extension: ffi Status: Verified
主要言語
C
スター
40.4k
フォーク
8.1k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

Description

The following code:

<?php

putenv("TEST=123");

var_dump((FFI::cdef("char *getenv(char *);", "/lib/x86_64-linux-gnu/libc.so.6"))->getenv("TEST"));

Resulted in an use-after-free:

FFI seems to free associated types instead of passing the type forward to the CData and refcounting them.

==571167== Invalid read of size 4
==571167==    at 0x441331: zend_ffi_cdata_get_debug_info (ffi.c:1975)
==571167==    by 0x90289D: zend_std_get_properties_for (zend_object_handlers.c:1912)
==571167==    by 0x902993: zend_get_properties_for (zend_object_handlers.c:1941)
==571167==    by 0x70AB9A: php_var_dump (var.c:163)
==571167==    by 0x70B19D: zif_var_dump (var.c:228)
==571167==    by 0x84E353: ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (zend_vm_execute.h:1250)
==571167==    by 0x8C5FE3: execute_ex (zend_vm_execute.h:55851)
==571167==    by 0x8CB80F: zend_execute (zend_vm_execute.h:60210)
==571167==    by 0x7F4369: zend_eval_stringl (zend_execute_API.c:1266)
==571167==    by 0x7F457D: zend_eval_stringl_ex (zend_execute_API.c:1308)
==571167==    by 0x7F45F6: zend_eval_string_ex (zend_execute_API.c:1318)
==571167==    by 0x989378: do_cli (php_cli.c:996)
==571167==  Address 0x769f150 is 0 bytes inside a block of size 88 free'd
==571167==    at 0x4A4292F: free (vg_replace_malloc.c:872)
==571167==    by 0x7CC99B: _efree_custom (zend_alloc.c:2438)
==571167==    by 0x7CCAF2: _efree (zend_alloc.c:2558)
==571167==    by 0x441EED: _zend_ffi_type_dtor (ffi.c:2252)
==571167==    by 0x43C4BA: zend_ffi_type_dtor (ffi.c:224)
==571167==    by 0x441EA6: _zend_ffi_type_dtor (ffi.c:2247)
==571167==    by 0x43C4BA: zend_ffi_type_dtor (ffi.c:224)
==571167==    by 0x441FD0: zend_ffi_symbol_hash_dtor (ffi.c:2282)
==571167==    by 0x8280E9: zend_hash_destroy (zend_hash.c:1695)
==571167==    by 0x442284: zend_ffi_free_obj (ffi.c:2353)
==571167==    by 0x90315A: zend_objects_store_del (zend_objects_API.c:200)
==571167==    by 0x83D5D7: zend_object_release (zend_objects_API.h:75)
==571167==  Block was alloc'd at
==571167==    at 0x4A40045: malloc (vg_replace_malloc.c:381)
==571167==    by 0x7CDE59: __zend_malloc (zend_alloc.c:3078)
==571167==    by 0x7CC92A: _malloc_custom (zend_alloc.c:2429)
==571167==    by 0x7CCA74: _emalloc (zend_alloc.c:2548)
==571167==    by 0x4531F3: zend_ffi_make_pointer_type (ffi.c:6196)
==571167==    by 0x461DEA: parse_pointer (ffi_parser.c:2660)
==571167==    by 0x46198C: parse_declarator (ffi_parser.c:2574)
==571167==    by 0x45FFFB: parse_declarations (ffi_parser.c:2024)
==571167==    by 0x464284: parse (ffi_parser.c:3549)
==571167==    by 0x464302: zend_ffi_parse_decl (ffi_parser.c:3561)
==571167==    by 0x444B64: zim_FFI_cdef (ffi.c:2915)
==571167==    by 0x84FC46: ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1885)
// more...
object(FFI\CData:char*)#2 (1) {
  [0]=>
  string(1) "1"
}
PHP Version

master

Operating System

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Valgrind で PHP FFI\CData の例を再現し、その後、トレースに示されている zend_ffi_cdata_get_debug_info()、zend_ffi_free_obj()、および FFI 型デストラクタの ffi.c を調査します。CData が使用する型が FFI オブジェクトの破棄後も有効なままであることを確認し、例で無効な読み取りが報告されなくなったことを検証します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c, php
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
38/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。