From 490452b67750cf2302efa7d537f186652cd0d15d Mon Sep 17 00:00:00 2001 From: Martin Mirchev Date: Thu, 22 Oct 2026 22:05:08 +0800 Subject: [PATCH 1/3] Fix infinite loop in sapi_header_op() for headers of 4 GiB or more The new line/NUL check iterated over the size_t header length with a uint32_t index, which wraps around for header lines of 4 GiB or more, so the loop never ended. session_start() reaches this with a cookie path, domain or session id of that size. Use size_t for the index. --- .../tests/session_cookie_path_over_4gib.phpt | 27 +++++++++++++++++++ main/SAPI.c | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 ext/session/tests/session_cookie_path_over_4gib.phpt diff --git a/ext/session/tests/session_cookie_path_over_4gib.phpt b/ext/session/tests/session_cookie_path_over_4gib.phpt new file mode 100644 index 000000000000..98b21a668bc7 --- /dev/null +++ b/ext/session/tests/session_cookie_path_over_4gib.phpt @@ -0,0 +1,27 @@ +--TEST-- +session_start() with a Set-Cookie header longer than 4 GiB +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +memory_limit=-1 +session.use_cookies=1 +session.use_only_cookies=1 +session.cache_limiter= +session.save_handler=files +--FILE-- + +--EXPECT-- +bool(true) diff --git a/main/SAPI.c b/main/SAPI.c index dbc6ed163309..4b6b7b0c90e6 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -742,7 +742,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) return SUCCESS; } else { /* new line/NUL character safety check */ - uint32_t i; + size_t i; for (i = 0; i < header_line_len; i++) { /* RFC 7230 ch. 3.2.4 deprecates folding support */ if (header_line[i] == '\n' || header_line[i] == '\r') { From ff3f66894c1fefb826fa385f449e233bddad87c7 Mon Sep 17 00:00:00 2001 From: Martin Mirchev Date: Thu, 22 Oct 2026 23:16:12 +0800 Subject: [PATCH 2/3] Test the sapi_header_op() fix with header() instead of the session Use header() directly, as suggested in review, so the test does not depend on the session extension. --- .../general_functions/header_over_4gib.phpt} | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) rename ext/{session/tests/session_cookie_path_over_4gib.phpt => standard/tests/general_functions/header_over_4gib.phpt} (55%) diff --git a/ext/session/tests/session_cookie_path_over_4gib.phpt b/ext/standard/tests/general_functions/header_over_4gib.phpt similarity index 55% rename from ext/session/tests/session_cookie_path_over_4gib.phpt rename to ext/standard/tests/general_functions/header_over_4gib.phpt index 98b21a668bc7..a2075dfb27cd 100644 --- a/ext/session/tests/session_cookie_path_over_4gib.phpt +++ b/ext/standard/tests/general_functions/header_over_4gib.phpt @@ -1,27 +1,20 @@ --TEST-- -session_start() with a Set-Cookie header longer than 4 GiB ---EXTENSIONS-- -session +header() with a header line longer than 4 GiB --SKIPIF-- --INI-- memory_limit=-1 -session.use_cookies=1 -session.use_only_cookies=1 -session.cache_limiter= -session.save_handler=files --FILE-- ---EXPECT-- -bool(true) +--EXPECTF-- +Warning: Header may not contain more than a single header, new line detected in %s on line %d +Done From 5ed81cdc01fc5eb4006d634e60f4057704bb3e7c Mon Sep 17 00:00:00 2001 From: Martin Mirchev Date: Thu, 22 Oct 2026 23:30:37 +0800 Subject: [PATCH 3/3] Add NEWS entry for the sapi_header_op() fix --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 599891f3b598..38a0c2ec1656 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,8 @@ PHP NEWS . Fixed bug GH-24321 (ZTS: global_map_ptr_last survives zend_shutdown(), so an in-process engine restart keeps growing the map_ptr table). (David Carlier) + . Fixed infinite loop in sapi_header_op() for headers of 4 GiB or more. + (Martin Mirchev) - Date: . Fixed bug GH-20503 (Assertion failure with ext/date DateInterval property