You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PHP uses longjmp() for out-of-memory (OOM) errors to exit the current context and abort handling of the request. In some contexts, request memory is temporarily reachable before it is fully initialized. If any allocation fails at that point, PHP does not properly account for the early exit and leaves the request memory in an invalid state. The failed allocation does not need to be related to the invalid memory. The request shutdown procedure may then read or branch on it. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).
Vulnerability
OOM strategies
Several multipart parsing problems can let a request reach OOM while remaining within its apparent PHP limits:
A multipart request without a usable declared content length may pass the initial post_max_size check and continue supplying decoded body data.
A multipart part can contain an unrestricted number of headers. Representing these headers inside PHP can use substantially more memory than their wire representation, allowing a request within post_max_size to exhaust the normal memory_limit.
Empty file controls do not count towards max_file_uploads but still create the normal file metadata arrays. Nested field names multiply the generated array work.
OOM can also be reached in application-specific ways when attacker-controlled input causes a sufficiently large allocation or repeated memory use.
Susceptibility
Apache mod_php unconditionally invokes the request shutdown procedure, even when request startup has failed. During request startup, automatic body parsing can exhaust the configured memory limit and exit the request in a context where state is temporarily invalid. Shutdown then processes this invalid state. This happens entirely before any application-specific code begins execution.
FPM exits the child when request startup fails. This prevents consumption of the invalid state and removes the child from the pool. After normal startup, OOM may still be reached in a context failing to account for an early exit, with the invalid state being processed during request shutdown. Source analysis therefore supports FPM as a susceptible, though no complete FPM exploit has been demonstrated for this SAPI.
Source analysis indicates that FrankenPHP, analogous to Apache mod_php, calls the request shutdown procedure unconditionally, making it likely susceptible to application-independent attacks. LSAPI models FPM, with application-specific exploits being likely but unvalidated.
Mitigation
The patch removes longjmp() for OOM, avoiding an early exit out of contexts that do not properly account for it. It is replaced with a delayed, graceful soft OOM triggered at the next VM safe point, and an immediate hard OOM using _exit() if memory consumption reaches a second, higher threshold. The shutdown procedure will no longer see invalid state, and PHP's normal ability to limit memory consumption is retained.
Warning
Updating to a PHP release containing the patch to this vulnerability is the only complete mitigation.
For installations that cannot update, setting and enforcing memory_limit=-1 administratively is the primary configuration mitigation. It removes the predictable per-request limit that enables the confirmed exploit with a controllable OOM. This is not a complete mitigation. If mmap() or another underlying allocation fails, PHP can still use longjmp() while incomplete request memory is reachable. Restart every PHP worker and confirm that no pool, directory or application setting restores a finite PHP memory limit.
Keep post_max_size conservative and independently enforce the decoded request size at the frontend. Reduce max_input_nesting_level, and bound the number of input variables, multipart parts, headers within each part and uploads. These controls reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating. If the application does not use multipart form data, block such requests at the frontend before they reach PHP.
A container or cgroup memory limit (memory.max) may provide an alternative to PHP's own memory_limit with some limitations. It is not guaranteed to prevent allocation failure and is not a complete mitigation. For example, killing a container or cgroup can also kill the master and every worker, unless each worker has its own group. Killing one FPM child fails only its current requests and FPM's master replaces it quickly. Do not use RLIMIT_AS or RLIMIT_DATA, as these will cause mmap() to fail once the memory limit is reached, triggering the vulnerable longjmp() path.
Important: Make sure to also follow the remediation advice from the related report. GHSA-6wmf-4rv5-p3rp
Impact and reliability
The confirmed impact is unauthenticated remote code execution as the web worker account. Complete remote code execution was validated over HTTP against mod_php with default PHP input and memory limits and normal prefork configurations with multiple workers. Additional workers and unrelated traffic can increase the required number of attempts but do not remove the condition. Exploit portability and reliability depend on the PHP build, extensions, frontend behavior and allocator layout.
The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory belongs to the code that operates on the new pointer.
Learn more on MITRE.
The product manages a group of objects or resources and performs a separate memory allocation for each object, but it does not properly limit the total amount of memory that is consumed by all of the combined objects.
Learn more on MITRE.
The product attempts to initialize a resource but does not correctly do so, which might leave the resource in an unexpected, incorrect, or insecure state when it is accessed.
Learn more on MITRE.
Summary
PHP uses
longjmp()for out-of-memory (OOM) errors to exit the current context and abort handling of the request. In some contexts, request memory is temporarily reachable before it is fully initialized. If any allocation fails at that point, PHP does not properly account for the early exit and leaves the request memory in an invalid state. The failed allocation does not need to be related to the invalid memory. The request shutdown procedure may then read or branch on it. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).Vulnerability
OOM strategies
Several multipart parsing problems can let a request reach OOM while remaining within its apparent PHP limits:
post_max_sizecheck and continue supplying decoded body data.post_max_sizeto exhaust the normalmemory_limit.max_file_uploadsbut still create the normal file metadata arrays. Nested field names multiply the generated array work.OOM can also be reached in application-specific ways when attacker-controlled input causes a sufficiently large allocation or repeated memory use.
Susceptibility
Apache mod_php unconditionally invokes the request shutdown procedure, even when request startup has failed. During request startup, automatic body parsing can exhaust the configured memory limit and exit the request in a context where state is temporarily invalid. Shutdown then processes this invalid state. This happens entirely before any application-specific code begins execution.
FPM exits the child when request startup fails. This prevents consumption of the invalid state and removes the child from the pool. After normal startup, OOM may still be reached in a context failing to account for an early exit, with the invalid state being processed during request shutdown. Source analysis therefore supports FPM as a susceptible, though no complete FPM exploit has been demonstrated for this SAPI.
Source analysis indicates that FrankenPHP, analogous to Apache mod_php, calls the request shutdown procedure unconditionally, making it likely susceptible to application-independent attacks. LSAPI models FPM, with application-specific exploits being likely but unvalidated.
Mitigation
The patch removes
longjmp()for OOM, avoiding an early exit out of contexts that do not properly account for it. It is replaced with a delayed, graceful soft OOM triggered at the next VM safe point, and an immediate hard OOM using_exit()if memory consumption reaches a second, higher threshold. The shutdown procedure will no longer see invalid state, and PHP's normal ability to limit memory consumption is retained.Warning
Updating to a PHP release containing the patch to this vulnerability is the only complete mitigation.
For installations that cannot update, setting and enforcing
memory_limit=-1administratively is the primary configuration mitigation. It removes the predictable per-request limit that enables the confirmed exploit with a controllable OOM. This is not a complete mitigation. Ifmmap()or another underlying allocation fails, PHP can still uselongjmp()while incomplete request memory is reachable. Restart every PHP worker and confirm that no pool, directory or application setting restores a finite PHP memory limit.Keep
post_max_sizeconservative and independently enforce the decoded request size at the frontend. Reducemax_input_nesting_level, and bound the number of input variables, multipart parts, headers within each part and uploads. These controls reduce hard OOM and denial of service risk even after applying the patch, but do not replace updating. If the application does not use multipart form data, block such requests at the frontend before they reach PHP.A container or cgroup memory limit (
memory.max) may provide an alternative to PHP's ownmemory_limitwith some limitations. It is not guaranteed to prevent allocation failure and is not a complete mitigation. For example, killing a container or cgroup can also kill the master and every worker, unless each worker has its own group. Killing one FPM child fails only its current requests and FPM's master replaces it quickly. Do not useRLIMIT_ASorRLIMIT_DATA, as these will causemmap()to fail once the memory limit is reached, triggering the vulnerablelongjmp()path.Important: Make sure to also follow the remediation advice from the related report.
GHSA-6wmf-4rv5-p3rp
Impact and reliability
The confirmed impact is unauthenticated remote code execution as the web worker account. Complete remote code execution was validated over HTTP against mod_php with default PHP input and memory limits and normal prefork configurations with multiple workers. Additional workers and unrelated traffic can increase the required number of attempts but do not remove the condition. Exploit portability and reliability depend on the PHP build, extensions, frontend behavior and allocator layout.