ArrayObject backing storage cycle causes unbounded recursion in spl_array_get_hash_table_ptr()

Aperta
#24,615 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
1-2 giorni
Idoneità per principianti
51/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c, php
Ambito
backend, devtools

Direzione di ricerca

Start in ext/spl/spl_array.c, especially spl_array_set_array() and spl_array_get_hash_table_ptr(), and trace how SPL_ARRAY_USE_OTHER follows ArrayObject or ArrayIterator backing storage. Check existing SPL tests for exchangeArray() and constructor behavior, then add coverage showing that creating a multi-object backing cycle raises an error without recursion; verify ordinary backing objects still work.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Description

ArrayObject::exchangeArray() (and the constructor) accept another ArrayObject as backing storage and only reject an object backing itself. Two objects that back each other are accepted silently, and the first operation that needs the storage recurses without limit in spl_array_get_hash_table_ptr() until the process crashes.

The following code:

<?php
$a = new ArrayObject([1]);
$b = new ArrayObject($a);   // $b uses $a's storage
$a->exchangeArray($b);      // $a now uses $b's storage: a cycle
echo "cycle built\n";
var_dump(count($a));

Resulted in this output (AddressSanitizer build):

==ERROR: AddressSanitizer: stack-overflow on address ...
    #0 spl_array_get_hash_table_ptr ext/spl/spl_array.c:65
    #1 spl_array_get_hash_table_ptr ext/spl/spl_array.c:71
    #2 spl_array_get_hash_table_ptr ext/spl/spl_array.c:71
    ...

But I expected this output instead: an error when the cycle is created (for example an InvalidArgumentException from exchangeArray()), as for other unsupported backing objects.

spl_array_set_array() sets SPL_ARRAY_USE_OTHER for any other ArrayObject/ArrayIterator and only special-cases Z_OBJ_P(object) == Z_OBJ_P(array); following the chain of SPL_ARRAY_USE_OTHER objects before accepting one would catch longer cycles too. Object backing storage is deprecated on master, but it is still accepted there.

Reproduced on 8.2.34-dev (512c04e39f) and 8.4.28-dev; the same code is on master.

This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually.

PHP Version
PHP 8.4.28-dev, PHP 8.2.34-dev
Operating System

Linux (Ubuntu 20.04, x86_64)

Lingua principale
C
Stelle
41.8k
Fork
8.5k
Merge medio
2g 13h
PR unite (30g)
145

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di php/php-src

Tutte le issue di php/php-src

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.