Repository navigation
Conversation
laruence
reviewed
Aug 26, 2026
| char *loc_path = NULL; | ||
| if (*header_info.location != '/') { | ||
| if (*(header_info.location+1) != '\0' && resource->path) { | ||
| if (header_info.location_len > 0 && *(header_info.location+1) != '\0' && resource->path) { |
Member
There was a problem hiding this comment.
hmm, this might not be related to your PR, but since it already have location_len, why it still call strlen(location) above?
Member
Author
There was a problem hiding this comment.
Switched to location_len.
Member
There was a problem hiding this comment.
do you still need *(header_info.location+1) != '\0' tough ?
Member
Author
There was a problem hiding this comment.
No. Empty Location is length 0. A 1-char relative path is valid, so location_len > 0 is enough.
iliaal
added a commit
to iliaal/php-src
that referenced
this pull request
Aug 26, 2026
An empty Location header allocates a single byte for the NUL terminator, so reading location[1] in the relative-redirect branch over-reads heap memory and could append a garbage-derived path to the redirect target instead of the correct host root. Guard the read with location_len before dereferencing the second byte, and use that length instead of strlen for the absolute-URL check. Closes phpGH-23467
iliaal
force-pushed
the
fix/http-empty-location-84
branch
from
August 26, 2026 12:22
5e412a6 to
330bb1e
Compare
iliaal
added a commit
to iliaal/php-src
that referenced
this pull request
Aug 26, 2026
An empty Location header allocates a single byte for the NUL terminator, so reading location[1] in the relative-redirect branch over-reads heap memory and could append a garbage-derived path to the redirect target instead of the correct host root. Use location_len instead of strlen, and require location_len > 1 before treating the value as a relative path, so the second byte is never read. Closes phpGH-23467
iliaal
force-pushed
the
fix/http-empty-location-84
branch
2 times, most recently
from
August 26, 2026 20:43
330bb1e to
8a54f0a
Compare
An empty Location header allocates a single byte for the NUL terminator, so reading location[1] in the relative-redirect branch over-reads heap memory and could append a garbage-derived path to the redirect target instead of the correct host root. Use location_len instead of strlen, and skip the relative join when location_len is 0, so the second byte is never read. Closes phpGH-23467
iliaal
force-pushed
the
fix/http-empty-location-84
branch
from
August 26, 2026 20:53
8a54f0a to
231f29f
Compare
laruence
approved these changes
Aug 27, 2026
devnexen
approved these changes
Aug 27, 2026
jordikroon
added a commit
to jordikroon/php-src
that referenced
this pull request
Aug 31, 2026
jordikroon
added a commit
to jordikroon/php-src
that referenced
this pull request
Aug 31, 2026
jordikroon
added a commit
to jordikroon/php-src
that referenced
this pull request
Aug 31, 2026
iliaal
added a commit
that referenced
this pull request
Sep 1, 2026
* PHP-8.5: ext/standard: Fix 1-char relative Location redirects after GH-23467
pull Bot
pushed a commit
to dolfly/php-src
that referenced
this pull request
Sep 1, 2026
8196275 changed the relative-Location check from location_len > 1 to > 0, so a single-character Location began resolving against the request path instead of the host root as before. Closes phpGH-23521
pull Bot
pushed a commit
to dolfly/php-src
that referenced
this pull request
Sep 1, 2026
* PHP-8.4: ext/standard: Fix 1-char relative Location redirects after phpGH-23467
bukka
added a commit
that referenced
this pull request
Sep 22, 2026
* PHP-8.2: ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable Add NEWS entries ext/standard: Fix 1-char relative Location redirects after GH-23467 [http] Fix out-of-bounds read on empty Location header Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED Fix GHSA-9f67-6fw4-hpfp Fix GHSA-j3wh-g957-2m85: phar tar entry injection Fix GHSA-cj93-vc83-wgqv Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name() Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars
bukka
added a commit
that referenced
this pull request
Sep 22, 2026
* PHP-8.3: ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable Add NEWS entries ext/standard: Fix 1-char relative Location redirects after GH-23467 [http] Fix out-of-bounds read on empty Location header Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED Fix GHSA-9f67-6fw4-hpfp Fix GHSA-j3wh-g957-2m85: phar tar entry injection Fix GHSA-cj93-vc83-wgqv Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name() Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars # Conflicts: # ext/openssl/xp_ssl.c
bukka
added a commit
that referenced
this pull request
Sep 22, 2026
* PHP-8.4: Skip bz2 GH-20807 test when less than 13 GiB of memory is available ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable Add NEWS entries ext/standard: Fix 1-char relative Location redirects after GH-23467 [http] Fix out-of-bounds read on empty Location header Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED Fix GHSA-9f67-6fw4-hpfp Fix GHSA-j3wh-g957-2m85: phar tar entry injection Fix GHSA-cj93-vc83-wgqv Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name() Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars # Conflicts: # NEWS # ext/phar/tar.c # ext/soap/php_http.c # ext/soap/php_xml.c # ext/standard/http_fopen_wrapper.c # win32/ioutil.c
bukka
added a commit
that referenced
this pull request
Sep 22, 2026
* PHP-8.5: Skip bz2 GH-20807 test when less than 13 GiB of memory is available ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable Add NEWS entries ext/standard: Fix 1-char relative Location redirects after GH-23467 [http] Fix out-of-bounds read on empty Location header Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED Fix GHSA-9f67-6fw4-hpfp Fix GHSA-j3wh-g957-2m85: phar tar entry injection Fix GHSA-cj93-vc83-wgqv Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name() Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars # Conflicts: # NEWS # ext/openssl/xp_ssl.c # ext/phar/tar.c # ext/soap/php_http.c # ext/standard/http_fopen_wrapper.c
devnexen
pushed a commit
to devnexen/php-src
that referenced
this pull request
Sep 22, 2026
An empty Location header allocates a single byte for the NUL terminator, so reading location[1] in the relative-redirect branch over-reads heap memory and could append a garbage-derived path to the redirect target instead of the correct host root. Use location_len instead of strlen, and skip the relative join when location_len is 0, so the second byte is never read. Closes phpGH-23467
devnexen
pushed a commit
to devnexen/php-src
that referenced
this pull request
Sep 22, 2026
8196275 changed the relative-Location check from location_len > 1 to > 0, so a single-character Location began resolving against the request path instead of the host root as before. Closes phpGH-23521
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 22, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, freed $_GET/$_POST/... pointers, SAPI request strings and header callback, modules_activated, the autoload guard table, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix, so that request variables cost as little memory as they can. Left out, as PHP 5 has no counterpart: HT_HASH_RESET of the PHP 7 hash tables; the CONCAT overflow checks of the PHP 7 VM are those of concat_function() here. Cross-checked with the independent 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch), which brought the singleton arrays, the reset of SG(callback_func) and the earlier reset of EG(error_handling) and EG(exception), and with the one of vperetti/php-cve-2026-109618-109619-backports (patches/php-5.6-CVE-2026-109618-109619.patch), which brought the reset of EG(in_autoload). Origin: azsupport, port of php-src commit 802c210 (PHP 7.4, Arnaud Le Blanc, 18.10.2026, cherry-pick of b62095c75da7; GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) to remicollet PHP-5.6-security-backports-openssl11 @ 5c2cc46; replaces backport-oom-exit.patch. Drop when that branch gets its own fix - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 22, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, freed $_GET/$_POST/... pointers, SAPI request strings and header callback, modules_activated, the autoload guard table, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix, so that request variables cost as little memory as they can. Left out, as PHP 5 has no counterpart: HT_HASH_RESET of the PHP 7 hash tables; the CONCAT overflow checks of the PHP 7 VM are those of concat_function() here. Cross-checked with the independent 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch), which brought the singleton arrays, the reset of SG(callback_func) and the earlier reset of EG(error_handling) and EG(exception), and with the one of vperetti/php-cve-2026-109618-109619-backports (patches/php-5.6-CVE-2026-109618-109619.patch), which brought the reset of EG(in_autoload). Origin: azsupport, port of php-src commit 802c210 (PHP 7.4, Arnaud Le Blanc, 18.10.2026, cherry-pick of b62095c75da7; GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp) to remicollet PHP-5.6-security-backports-openssl11 @ 5c2cc46; replaces backport-oom-exit.patch. Drop when that branch gets its own fix - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
azsupport
added a commit
to azsupport/php-src
that referenced
this pull request
Oct 23, 2026
Interim backports carried until the upstream branch has its own fix: - backport-convert-filters.patch: GHSA-88hq-2827-7pg6: the convert.base64-encode, convert.quoted-printable-encode and convert.quoted-printable-decode stream filters copy their line-break-chars option with its length (pestrndup()), so that a value with a NUL byte no longer leads to a heap buffer over-read. Origin: php-src commit 8d933a6 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.02.2026, geeknik, cherry-pick of b4e3397), applies to 5.6 as it is - backport-date-period.patch: DatePeriod::__construct() called again on the same object frees the start, current, end and interval of the first call instead of leaking them (phpGH-22643), and refuses a DateInterval, or a start or end date, that was not initialized by its constructor (a subclass that overrides it without calling the parent) instead of reading through a NULL pointer; unlike the 7.4 version it restores the error handling mode on that path, so that later warnings do not turn into exceptions. Origin: php-src commit bbb0272 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (07.07.2026, Ilija Tovilo), adapted to the PHP 5.6 object layout; the check of the start and end dates is added here (5.6 copies the start time with memcpy()) - backport-filter-encoded.patch: GHSA-ch8v-r6jh-4vvr: FILTER_SANITIZE_ENCODED percent-encodes 0xFF (its table of characters to keep was one byte short and left 0xFF as it is). Origin: php-src commit f517508 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (29.07.2026, Ilia Alshanetsky), applies to 5.6 as it is - backport-fpm-allowed-clients.patch: GHSA-62xp-839h-2637: listen.allowed_clients of php-fpm compared only the first 96 bits of an IPv6 client address, so that an allowed ::dead:beef let ::1 in; all 128 bits are compared now. Origin: php-src commit 7fb8053 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (25.08.2026, Alexandre Daubois), in sapi/fpm/fpm/fastcgi.c of 5.6 (main/fastcgi.c of 7.x); the test is rewritten for the FPM test helpers of 5.6, the IPv4-mapped one is left out (php-fpm 5.6 does not clear IPV6_V6ONLY, which FreeBSD sets by default) - backport-gd-gif-lzw.patch: CVE-2026-9672: the GIF LZW decoder of the bundled libgd (imagecreatefromgif()) clears every entry of its code table on a clear code (it cleared table[1][0] over and over and left the other entries stale), stops at the end code instead of decoding on with a stale code, and starts from a zeroed state, so that a crafted GIF cannot make it read uninitialized memory. Origin: php-src commit e9413a5 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (28.07.2026, libgd fix fcd691b by Pierre Joye), applies to 5.6 as it is - backport-http-redirects.patch: GHSA-fpwc-w8rq-cr92: on a redirect to another origin (scheme, host or port) the http:// stream wrapper drops Authorization, Cookie and Proxy-Authorization from the header option of the context, repeated headers, folded values and whitespace before the colon included; with it phpGH-11274: 307 and 308 redirects keep the method (POST, PATCH) and the body, as RFC 7231 and RFC 7538 require. The fixes of 7.4 for an empty and a 1-character Location (phpGH-23467, phpGH-23521) do not apply: 5.6 does not follow an empty Location and reads it from a fixed-size buffer. Origin: php-src commits c812ca1 (phpGH-11274, Niels Dossche) and dc1f36a (14.09.2026, Alexandre Daubois, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-mysqlnd-overread.patch: GHSA-h35g-vwh6-m678 (CVE-2024-8929, 2024) and the 2026 partial fix of GHSA-r6x9-5r99-36j7 for PHP 5.6: a hostile or man-in-the-middle MySQL server could make the mysqlnd client read past the end of a received packet and leak adjacent heap bytes into PHP-visible values, and in some paths free memory wrongly. 5.6 shipped neither fix (both are absent from Remi and Sury for 5.6), so both are carried over from PHP 7.4. php_mysqlnd_net_field_length() now takes the bytes left in the packet and returns MYSQLND_INVALID_NET_FIELD_LENGTH when a length-encoded integer would read past them; a new php_mysqlnd_net_field_length_ll() returns an optional value the callers must check. Every packet reader (greeting, auth response, OK, EOF, result-set header, column definition, prepare response, change-user, sha256 public key, and the text and binary row decoders) is bounded with BAIL_IF_NOT_ENOUGH_DATA_EX / explicit remaining-size checks, NUL-terminated strings are found with memchr instead of being assumed terminated, and the prepared-statement value decoders (ps_fetch_*) reject a declared length that runs past the row or is too short for the fixed type. A decode that fails frees or NULLs the already-decoded row zvals of 5.6 so the row can be freed safely, the BIT text value is bounded by the space reserved from the column length, read_result_metadata frees a failed result through free_result (not a bare efree that would leak the sub-objects), and the prepared-statement EOF reset releases the connection reference and command buffer before the memset. Tests use a new fake MySQL server (ext/mysqli/tests/fake_server.inc), adapted to PHP 5.6 syntax; the client handshake bytes that differ in 5.6 are matched with %s. Origin: azsupport, port of php-src commits 2f5aa9f (GHSA-h35g-vwh6-m678 / CVE-2024-8929, Jakub Zelenka, 08.10.2024, PHP-8.1) and 2af14de (Partial Fix GHSA-r6x9-5r99-36j7, Jakub Zelenka and Nora Dossche, 12.07.2026) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) - backport-openssl-peer-name.patch: GHSA-vvx9-73fr-5jjx: the peer name check of TLS streams no longer falls back to the CN when the certificate presents a DNS-ID, URI-ID or SRV-ID (RFC 6125 6.4.4); GHSA-xr7j-rvgx-xq5p: out-of-bounds read in the wildcard match when the wildcard prefix and suffix overlap in the name (CN "a*aaaa" against "aaaa"). The tests come with CertificateGenerator.inc of 7.4. Origin: php-src commits da1db02 and dbc0299 of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (10.08.2026, Jakub Zelenka) - backport-pgsql-quotes.patch: GHSA-7qpv-r5mr-78m4 (CVE-2026-17543): SQL injection through pg_convert(), pg_insert(), pg_update(), pg_delete() and pg_select(): values escaped with PQescapeStringConn() were quoted as E'...', where a backslash escapes the quote, while PQescapeStringConn() doubles backslashes only with standard_conforming_strings off; they are quoted as '...' now. Origin: php-src commit 6a80d9d of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports) (27.07.2026, Ilija Tovilo, cherry-pick of ab048bd), with the expected results of the pgsql tests - backport-phar-tar.patch: GHSA-vc5h-9ppw-p5f3 (CVE-2026-7260): a tar archive with a loop of symbolic links no longer exhausts the stack (phar_get_link_source() follows the chain without recursion, with Floyd's cycle detection; a loop resolves to nothing). GHSA-j3wh-g957-2m85: tar entry injection: an entry size that is not plain octal (overflow, GNU base-256, other characters) is refused instead of being read as some other size, entries that carry no data (links, devices, directories, FIFOs) no longer skip data, GNU long link records are refused and a long name longer than the archive is rejected. The test of GHSA-vc5h writes its archives itself, as patch(1) cannot add the binary ones of upstream. Origin: php-src commits 6982130 (03.05.2026) and f3432d2 (13.09.2026, both Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), ported to the PHP 5 API - backport-php2shell-1.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6: the official EOL fix "Avoid state corruption via bailout" (PHP 7.4) carried over to the PHP 5 engine, as proposed for remicollet/php-src-security in pull request php#32: fatal errors of the allocator (memory limit, integer overflow in allocation sizes, string size overflow in concatenation, Balloc) print and _exit() the worker instead of a zend_error() longjmp() out of a half-initialized request; state that an error before the next request startup can reach is reset (user error and exception handler stacks, error handling mode, exception, the autoload guard table, freed $_GET/$_POST/... pointers, SAPI request strings, modules_activated, zend_llist head and tail); multipart parsing keeps only Content-Disposition and Content-Type headers, without duplicates; session upload progress stays off whatever session.upload_progress.enabled says. The code of that pull request as it is, so that sync skips this patch once the branch has it; what the official fix and the other 5.6 ports have on top is in backport-php2shell-2-extra.patch. Origin: remicollet/php-src-security#32 (RalphJS, 22.10.2026), commit 477c04a64, port of php-src 802c210 (PHP 7.4, Arnaud Le Blanc) to PHP-5.6-security-backports-openssl11 @ 5c2cc46; the same code as our own port of 22.10.2026 (131fde8), which it replaces. Skipped by sync once the branch has it - backport-php2shell-2-extra.patch: CVE-2026-109618 and CVE-2026-109619 for PHP 5.6, on top of backport-php2shell-1.patch: what the official fix and the other 5.6 ports have and that patch has not. $_GET, $_POST, $_COOKIE and their sub-arrays start as the smallest array (2 buckets: nTableMask 0 marks an uninitialized table in PHP 5), as the singleton arrays of the official fix; EG(error_handling) and EG(exception) are reset right after the object store is freed, where the official fix does it, so that an error in the rest of the shutdown cannot reach the freed exception; EG(exception_class) is reset with the handlers; SG(callback_func), the header callback of the request, is reset after it; "Out of memory" of the persistent allocator wrappers ends with _exit() instead of exit(), so that no atexit handler runs in that state. Origin: azsupport, from our port of 22.10.2026 (131fde8): the singleton arrays and the early reset from php-src 802c210 (PHP 7.4, Arnaud Le Blanc), SG(callback_func) from the 5.6 port of Ondrej Sury (php5.6 5.6.40-104, debian/patches/0261-Avoid-state-corruption-via-bailout.patch) - backport-soap.patch: GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap: a deeply nested WSDL or SOAP message, or a chain or loop of href references, no longer overflows the stack (iterative cleanup and search, at most 2048 levels of XML with libxml2 older than 2.13, at most 4096 levels of decoding: "Encoding: Nesting level too deep"); GHSA-cj93-vc83-wgqv: the HTTP reader of SoapClient keeps the chunk sizes and the body length within bounds (unsigned sizes, explicit limits instead of a signed overflow check). Origin: php-src commits 0a51c0d (17.09.2026, Alexandre Daubois) and 9b8abad (13.09.2026, Nora Dossche, Jakub Zelenka) of the PHP 7.4 security branch of Remi Collet (remicollet/php-src-security PHP-7.4-security-backports), with the test of 0c5cff7; the limits follow the int body length of 5.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a server sends a redirect with an empty Location header, the wrapper allocates a single byte for it and the relative-redirect branch then reads location[1], one byte past the allocation, so a hostile server can make the over-read pick up heap garbage and turn the redirect target into the current path plus junk instead of the host root. The second-byte dereference is now guarded by header_info.location_len; an empty Location deterministically redirects to the host root. Sibling audit found no other unguarded indexing of header_info.location.