[php-src] PR #24540: Fix infinite loop in sapi_header_op() for headers of 4 GiB or more
| From: | Marti2203 | Date: | Thu, 22 Oct 2026 14:23:12 +0000 |
| Subject: | [php-src] PR #24540: Fix infinite loop in sapi_header_op() for headers of 4 GiB or more | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39704@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24540
Author: Marti2203
The new line/NUL check in
sapi_header_op() walks the header line with a
uint32_t index, but header_line_len is a size_t:
```c
uint32_t i;
for (i = 0; i < header_line_len; i++) {
```
For a header line of 4 GiB or more the index wraps around before it reaches the length, so the loop
never ends and the request hangs, burning CPU until something kills it.
header() and setcookie() do not reach this, because they cast the length
to uint32_t before calling sapi_header_op(). The session extension does:
php_session_send_cookie() passes the full size_t length of the Set-Cookie
line to sapi_add_header_ex(). So session_start() with a cookie path,
cookie domain or session id of 4 GiB or more hangs. This can only be triggered by the script itself
(it needs a huge INI value and a very large memory_limit), so it is a robustness fix, not a security
one.
### Reproducer
```php
<?php
ini_set('session.save_path', sys_get_temp_dir());
ini_set('session.use_cookies', '1');
ini_set('session.cookie_path', '/' . str_repeat('p', (1 << 32) +
16));
session_start();
echo "done\n";
```
Run with php -n -d memory_limit=-1 (needs about 17 GB of RAM).
- Before: with a cookie path 64 bytes shorter than 4 GiB, session_start() returns after
about 9 s. With the 4 GiB + 16 byte path it is still spinning in sapi_header_op() when
timeout 90 kills it.
- After: session_start() returns after about 9 s in both cases.
### Fix
Use size_t for the index.
### Test
ext/session/tests/session_cookie_path_over_4gib.phpt calls session_start()
with a cookie path longer than 4 GiB and checks that it returns. It needs about 17 GB of RAM, so it
follows the existing large-memory tests (e.g. ext/bz2/tests/gh20620.phpt): it only runs
with RUN_RESOURCE_HEAVY_TESTS set, on 64-bit platforms, and not with
SKIP_SLOW_TESTS.
- Without the fix: the test times out.
- With the fix: the test passes (about 14 s); without RUN_RESOURCE_HEAVY_TESTS it is
skipped.
- ext/session/tests, tests/basic and sapi/cli/tests pass (374
passed, 127 skipped, 1 expected fail, 0 failed).
This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually.
🤖 Generated with [Claude Code](https://claude.com/claude-code)