php / php/php-src

Use-after-free of call_user_func() function name via autoloader

Đang mở
#22,878 2 bình luận 0 reaction 1 người được giao Xem trên GitHub

@iliaal đang làm issue này rồi.

Từ ngày 24/7/2026.

  • #22881 của @iliaal — đang mở
Bug Extension: standard Status: Verified
Ngôn ngữ chính
C
Star
40.4k
Fork
8.1k
Merge trung bình
2 ngày 13 giờ
Pull request đã merge (30 ngày)
96

Mô tả

Description
Problem

I found a use-after-free in zend_is_callable_at_frame(). The function borrows
pointers to the class and method elements of an array callable. Validating the
class can invoke an autoloader, and that autoloader can release the array. PHP
then passes the freed method element to zend_is_callable_check_func().
Both call_user_func() and call_user_func_array() reach the same vulnerable
code, so I have included both entry points in this report.

Minimal reproducers

call_user_func():

<?php
spl_autoload_register(function (string $class): void {
$GLOBALS['cb'] = null;
eval('class TriggerAutoload { public static function __callStatic($n, $a) {} }');
});
$method = str_repeat('m', 256);
$cb = ['TriggerAutoload', $method];
unset($method);
call_user_func($cb);

call_user_func_array():

<?php
spl_autoload_register(function (string $class): void {
$GLOBALS['cb'] = null;
eval('class TriggerAutoload { public static function __callStatic($n, $a) {} }');
});
$method = str_repeat('m', 256);
$cb = ['TriggerAutoload', $method];
unset($method);
call_user_func_array($cb, []);

I built PHP 8.5.8 from the official source archive with:

CC=gcc CFLAGS="-O2 -g -fno-omit-frame-pointer" \
./configure --enable-cli --disable-all --disable-cgi --disable-phpdbg \
--disable-fpm --without-sqlite3 --without-pdo-sqlite
make -j8

Run both files:

sapi/cli/php -n poc-call-user-func.php
echo $?
sapi/cli/php -n poc-call-user-func-array.php
echo $?
Expected behavior

Each call should resolve TriggerAutoload, dispatch through __callStatic(),
and exit normally. Validation must not access the callable after its storage
has been freed.

Actual behavior

Each reproducer exits with status 139 (SIGSEGV) on an optimized PHP 8.5.8
build. Both results reproduced in 100 of 100 fresh processes on macOS arm64.
The official php:8.5.8-cli-bookworm image also crashed in 100 of 100 fresh
processes for each entry point on Linux x86_64.

PHP Version
Primary tested release:
PHP 8.5.8 (cli) (built: Jul 24 2026 17:30:12) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.5.8, Copyright (c) Zend Technologies
with Zend OPcache v8.5.8, Copyright (c), by Zend Technologies
Operating System

macOS 26.5.2, build 25F84, Darwin 25.5.0, arm64

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.