FFI\CData use-after-free after FFI object destroyed
未关闭
还没有人认领这个 Issue。
Bug
Extension: ffi
Status: Verified
- 主要语言
- C
- 星标
- 40.4k
- 派生
- 8.1k
- 平均合并
- 2 天 13 小时
- 30 天内合并 PR
- 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
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
在 Valgrind 下复现 PHP FFI\CData 示例,然后检查 ffi.c 中的 zend_ffi_cdata_get_debug_info()、zend_ffi_free_obj() 以及 trace 中显示的 FFI 类型析构函数。确保 CData 使用的类型在 FFI 对象销毁后仍然有效,并验证该示例不再报告无效读取。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- c, php
- 领域
- backend
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 38/100