HTTP wrapper leaks dechunk filter when header parsing fails after Transfer-Encoding: chunked
Maintainer antworten meist innerhalb von 1 Tag
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 78/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Bereich
- backend, networking
Rechercherichtung
Beginne in ext/standard/http_fopen_wrapper.c beim Parsen der Response-Header und beim Bereinigungspfad out:; das Issue zeigt, wo der Dechunk-Filter erstellt wird und wo die Bereinigung ihn nach einem fehlerhaften Header überspringt. Reproduziere den Fehler mit den bereitgestellten server.php- und client.php-Befehlen und prüfe anschließend den Leak-Bericht des Debug-Builds. Als abgeschlossen gilt die Arbeit, wenn der fehlgeschlagene Request keine Leaks meldet und eine korrekt formatierte chunked Response weiterhin funktioniert.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Description
The following code:
server.php (run first, php server.php):
<?php
$srv = stream_socket_server("tcp://127.0.0.1:18231", $errno, $errstr);
$conn = stream_socket_accept($srv);
while (($line = fgets($conn, 8192)) !== false) { if (trim($line) === '') break; }
// Transfer-Encoding: chunked, then a malformed header line
fwrite($conn, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nBrokenHeaderNoColon\r\n\r\n");
fclose($conn);
client.php (debug build, php -d report_memleaks=1 client.php):
<?php
@file_get_contents("http://127.0.0.1:18231/");
Resulted in this output:
ext/standard/filters.c(1885) : Freeing 0x... (16 bytes), script=.../client.php
main/streams/filter.c(267) : Freeing 0x... (80 bytes), script=.../client.php
=== Total 2 memory leaks detected ===
But I expected this output instead:
(no leaks reported)
Root cause: when the response carries Transfer-Encoding: chunked, the wrapper creates a dechunk filter while parsing headers (php_stream_filter_create, ext/standard/http_fopen_wrapper.c:379 in 8.5.12, :366 on master). If a later header line is malformed, header_info.error is set, the caller closes the stream and jumps to out: (master :1052-1058). The out: cleanup only appends the filter to the stream's readfilters when stream != NULL (master :1257-1259), so on the error path the filter is never freed. Per failed request this leaks the php_stream_filter struct (80 bytes) plus the dechunk filter data (16 bytes).
Reproduces on current master (8.7.0-dev) as well.
Suggested patch (verified against master: repro reports 0 leaks after patching; well-formed chunked responses unaffected):
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -1230,6 +1230,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
efree(header_info.location);
}
+ /* On the error path stream is NULL and the filter is never appended
+ * to readfilters below, so it must be freed here. */
+ if (header_info.transfer_encoding != NULL && stream == NULL) {
+ php_stream_filter_free(header_info.transfer_encoding);
+ header_info.transfer_encoding = NULL;
+ }
+
if (resource) {
php_uri_struct_free(resource);
}
PHP Version
PHP 8.5.12 (also reproduces on master, 8.7.0-dev)
Operating System
Linux x86_64
- Vorherrschende Sprache
- C
- Sterne
- 40.7k
- Forks
- 8.3k
- Ø Merge
- 17 Std. 29 Min.
- Gemergte PRs (30 T.)
- 10
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus php/php-src
-
Case-insensitive substr_compare, ksort, krsort are still locale-dependentEvtl. vergeben Ein verknüpfter Pull Request ist offen oder bereits gemergt. OffenBug Status: Needs Triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 73/100
php/php-src#24552 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Bug Status: Needs Triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
Bug Status: Needs Triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 71/100
php/php-src#24505 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
master: part of the mbstring bailout fix got lost in a mergeEvtl. vergeben @lazerg hat das vor 1 Tag übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
Maintainer antworten meist innerhalb von 1 Tag
-
Bug Status: Needs Triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 64/100
Maintainer antworten meist innerhalb von 1 Tag
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 66/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
MerginMaps/geodiff#272 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
open-quantum-safe/liboqs#2644 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
espressif/esp-adf-libs#89 · 1 Kommentar ·
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 88/100
Maintainer antworten meist innerhalb von 2 Tagen