Skip to content

fix: avoid longjmp crash on ARM64/macOS when connection is aborted#2304

Closed
johanjanssens wants to merge 1 commit intophp:mainfrom
johanjanssens:fix/arm64-connection-abort
Closed

fix: avoid longjmp crash on ARM64/macOS when connection is aborted#2304
johanjanssens wants to merge 1 commit intophp:mainfrom
johanjanssens:fix/arm64-connection-abort

Conversation

@johanjanssens
Copy link
Copy Markdown

php_handle_aborted_connection() calls zend_bailout() which does a longjmp(). On ARM64/macOS with Pointer Authentication (PAC), the jmp_buf signature check fails because the buffer was signed in a different stack frame, causing a SIGBUS crash.

Inline the effect of php_handle_aborted_connection() without calling zend_bailout():

set PG(connection_status) = PHP_CONNECTION_ABORTED 
php_output_set_status(PHP_OUTPUT_DISABLED)

PHP detects the abort at safe points (between opcodes via zend_interrupt checks) instead of longjmping out of the SAPI write handler.

This matches the approach used by Nginx Unit's PHP SAPI: https://github.com/nginx/unit/blob/master/src/nxt_php_sapi.c#L271

Affects both frankenphp_ub_write and frankenphp_sapi_flush.

php_handle_aborted_connection() calls zend_bailout() which does a
longjmp(). On ARM64/macOS with Pointer Authentication (PAC), the
jmp_buf signature check fails because the buffer was signed in a
different stack frame, causing a SIGBUS crash.

Inline the effect of php_handle_aborted_connection() without calling
zend_bailout(): set PG(connection_status) = PHP_CONNECTION_ABORTED and
php_output_set_status(PHP_OUTPUT_DISABLED). PHP detects the abort at
safe points (between opcodes via zend_interrupt checks) instead of
longjmping out of the SAPI write handler.

This matches the approach used by Nginx Unit's PHP SAPI:
https://github.com/nginx/unit/blob/master/src/nxt_php_sapi.c#L271

Affects both frankenphp_ub_write and frankenphp_sapi_flush.
@henderkes
Copy link
Copy Markdown
Contributor

How nasty, I don't have a mac to verify this, but the solution is plausible. I can't think of a better one to fix the cross-context jump.

@dunglas
Copy link
Copy Markdown
Member

dunglas commented Mar 25, 2026

Shouldn't this be patched directly in PHP?

@johanjanssens
Copy link
Copy Markdown
Author

I don't think so. The php_handle_aborted_connection() works correctly in PHP core. Other SAPIs (Apache, Nginx Unit) call it from their write handlers without issues.

That said, I can no longer reproduce the crash with the latest FrankenPHP, I had the issue on 11.3, when switching to Go 1.26.0. Didn't test anymore without the fix. Done so now to confirm, and can no longer break it.

Closing it, will re-open if this pops up again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants