php / php/php-src

Bucket brigade UAF

Offen
#22,845 4 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@iliaal arbeitet bereits daran.

Seit 21.7.2026.

  • #22850 von @iliaal — offen
Bug Category: Streams Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.2k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

php_user_filter's filter($in, $out, ...) receives $in and $out as PHP resources created by zend_register_resource() in userfilter_filter() but those php_stream_bucket_brigade structures are allocated on the C stack of the calling function (brig_a/brig_b in _php_stream_filter_flush, filter.c:452; brig_in/brig_out in _php_stream_filter_append filter.c:366). The le_bucket_brigade resource type has no destructor (user_filters.c:91), and after the callback returns the code only runs zval_ptr_dtor() on its local references (user_filters.c:249-250) without ever calling zend_list_close() so a resource copy stashed by userland (e.g. $GLOBALS['x'] = $in;) survives with res->ptr still pointing at the now-freed stack frame. When that stale resource is later passed to stream_bucket_make_writeable() or stream_bucket_append(), zend_fetch_resource() succeeds (it only checks the resource type, not liveness) and returns the dangling brigade pointer, which is then dereferenced - a use-after-free read and via brigade->tail->next = bucket a use-after-free write into freed stack memory. The root cause is that a request-lived PHP resource is allowed to outlive its stack-allocated backing store without being invalidated. The fix is to call zend_list_close(Z_RES(args[0])) / zend_list_close(Z_RES(args[1])) immediately after the filter() call (before the zval_ptr_dtors) so any stored copies become non-fetchable, or to stop backing these resources with stack memory.

PHP Version
8.6.0-dev
Operating System

No response

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.