- Replace bailout on OOM with UnwindExit
- Properly reset various globals that may be accessed during startup
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
* Run brew update in macOS CI
* Drop intel macOS from CI
* Fix build on Apple Clang 17+ (#18629)
Fixing "invalid cpu feature string for builtin" errors that started to appear on Apple Clang 17.0.0
(cherry picked from commit 772479ea2f)
* Cleanup macOS job in test-suite.yml
---------
Co-authored-by: Máté Kocsis <kocsismate@woohoolabs.com>
Apply the upstream backports listed for PCRE2 10.40 in SUPPORT-LIFECYCLE.md through 10.49 (GHSA-2p8c-ff85-vh9x, GHSA-q8g2-wprr-34m9, GHSA-9qww-pwc4-77qq, GHSA-fmgr-6ggq-9859, GHSA-3r4p-g7gg-ppmf, GHSA-r9hj-j2rw-4q3m), adapted to 10.40 where the patched code differs. Disable the legacy ARM64 NEON SIMD scanning for GHSA-43gg-c3xx-7w7g, as the upstream fix is a rewrite with no small backport.
Closes GH-24011.
The regression test for GHSA-cj93-vc83-wgqv sends a 2 GiB chunked body so
that the client-side 32-bit length arithmetic overflows. Building that
body as a PHP string and wrapping it in a data:// stream materialised the
payload several times (str_repeat, concatenation, and the data:// copy),
and those buffers lingered in the client process after the fork. Total
footprint reached ~8 GiB and the run took ~16s locally, far more under
slower/opcache CI jobs where it swapped and hit the run-tests timeout.
Replace the generic http_server() helper with a minimal server that
streams the 2 GiB filler in 8 MiB blocks. The bytes the client sees are
identical, so the code path under test is unchanged, but the sender's
memory stays small: only the client holds the large buffers (~4 GiB).
Run time drops to ~4s and peak memory roughly halves.
Also raise the free-RAM skip threshold from 4G to 6G to match the ~4 GiB
the client actually allocates, so the test skips rather than swaps on
memory-constrained machines.
8196275133 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 GH-23521
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 GH-23467
php_filter_encode_url() initialized its 256-byte "must encode" table with
memset(tmp, 1, sizeof(tmp) - 1), leaving tmp[255] uninitialized. Whether
0xFF got percent-encoded then depended on stack garbage; valgrind reports
the read as a conditional jump on an uninitialised value. Initialize the
whole table.
Backport of 56149186d8 from PHP-8.4.
Reject Windows reserved device names (CON, NUL, COM1, ...) used as a path
component in filesystem operations. Bare device names and DOS device
paths keep working.
Co-authored-by: Jakub Zelenka <bukka@php.net>
Reject entry sizes that cannot be parsed or represented, and skip the data
blocks of every entry type that carries data. Both left the stream on
attacker controlled data that was then parsed as a tar header.
Authorization, Cookie and Proxy-Authorization set through the http context
were forwarded verbatim when follow_location sent the request to another
origin. They are now stripped from the user header bag whenever the
redirect target differs in scheme, host or port, including when the header
name is repeated or the bag uses malformed line endings.
Co-authored-by: Jakub Zelenka <bukka@php.net>
RFC 6125 6.4.4 forbids matching CN-ID if the certificate presents a DNS-ID,
SRV-ID or URI-ID. Falling back allowed a CA that validated only one of those
identities to leave an unvalidated CN to be matched as a host name.
IP-ID is left out as it is out of scope of RFC 6125 and suppressing CN there
would break IP-only SAN certificates.
Use pestrndup() instead of pestrdup() when duplicating lbchars in the
base64-encode, quoted-printable-encode, and quoted-printable-decode
filter constructors. pestrdup() is strlen-based and truncates at the
first NUL byte, but lbchars_len preserves the original length, causing
an out-of-bounds read when the filter later copies lbchars_len bytes
from the truncated allocation.
Fixes GHSA-88hq-2827-7pg6.
php_pgsql_add_quotes() quotes the string with E'...', but PQescapeStringConn()
does not escape \ unless standard_conforming_strings is off.
PQescapeStringConn() is meant to be used with '', so do that instead.
Fixes GHSA-7qpv-r5mr-78m4
This reverts commit fa47ae16a1.
On macOS in GitHub Actions, pthread_jit_write_protect_supported_np() returns
false. So, there's really no point in running JIT with it in the first place.
We'll still need to tweak some tests when they explicitly enable the JIT.
The self-signed certificate the FTP test server presents
(ext/ftp/tests/server.inc) was generated in 2016 with a ten-year
validity and expired on 2026-07-23, so ext/ftp/tests and the ftps://
stream tests (ext/standard/tests/streams/opendir-003 and -004) fail the
TLS handshake with "certificate expired" on every branch. Regenerate it
as a self-signed CN=127.0.0.1 certificate that expires 2099-12-31, so
the suite does not silently break again on a ten-year cadence.