Skip to content

php-fpm: zend_mm_heap corrupted with cgi-fcgi request #15395

Closed
@verfriemelt-dot-org

Description

@verfriemelt-dot-org

Description

after making a request with a HTTP_AUTHORIZATION header, a subsequent cgi-fcgi -bind -connect 127.0.0.1:9000 will fail and cause heap corruption + SIGABRT on the child process.

poc:

$ docker run --rm -it --entrypoint bash php:fpm
# apt-get update && apt-get install tzdata locales libfcgi0ldbl -y
# php-fpm &
[1] 706
[13-Aug-2024 21:41:57] NOTICE: fpm is running, pid 706
[13-Aug-2024 21:41:57] NOTICE: ready to handle connections

# HTTP_AUTHORIZATION="Basic Zm9vOg==" SCRIPT_NAME=/ SCRIPT_FILENAME=/ REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 - foo 13/Aug/2024:21:42:21 +0000 "GET /" 404
Status: 404 Not Found
X-Powered-By: PHP/8.3.10
Content-type: text/html; charset=UTF-8

File not found.

with that, the setup is complete and you can now trigger the bug with this running in the container:

# cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 -  13/Aug/2024:21:42:39 +0000 "- " 200
X-Powered-By: PHP/8.3.10
Content-type: text/html; charset=UTF-8

# cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 - 0 B* 13/Aug/2024:21:42:40 +0000 "- " 200
zend_mm_heap corrupted
[13-Aug-2024 21:42:40] WARNING: [pool www] child 707 exited on signal 6 (SIGABRT) after 42.713030 seconds from start
[13-Aug-2024 21:42:40] NOTICE: [pool www] child 712 started

you might need to retry to hit the correct child which served the previous request.

this seems to affect at least all php 8 versions starting with 8.0.0
i did not check older version though.

root@abbd54a452e3:/var/www/html# [13-Aug-2024 21:44:47] NOTICE: fpm is running, pid 876
[13-Aug-2024 21:44:47] NOTICE: ready to handle connections
HTTP_AUTHORIZATION="Basic Zm9vOg==" SCRIPT_NAME=/ SCRIPT_FILENAME=/ REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 - foo 13/Aug/2024:21:44:50 +0000 "GET /" 404
Primary script unknownStatus: 404 Not Found
X-Powered-By: PHP/8.0.0
Content-type: text/html; charset=UTF-8

File not found.
root@abbd54a452e3:/var/www/html# cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 -  13/Aug/2024:21:44:54 +0000 "- " 200
X-Powered-By: PHP/8.0.0
Content-type: text/html; charset=UTF-8

root@abbd54a452e3:/var/www/html# cgi-fcgi -bind -connect 127.0.0.1:9000
127.0.0.1 - 0��& 13/Aug/2024:21:44:55 +0000 "- " 200
zend_mm_heap corrupted
[13-Aug-2024 21:44:55] WARNING: [pool www] child 877 exited with code 1 after 8.593094 seconds from start
root@abbd54a452e3:/var/www/html# [13-Aug-2024 21:44:55] NOTICE: [pool www] child 882 started

we use the connect to the port 9000 as a liveness probe for kubernetes like this:

livenessProbe:
    initialDelaySeconds: 10
    exec:
        command:
            - /usr/bin/cgi-fcgi -bind -connect 127.0.0.1:9000

and we noticed a service with that setup failing due to the command returning a non-zero exit code and the thus the pod being restarted while the service receives requests with HTTP_AUTH headers.
the bug can not be triggered without the HTTP_AUTHORIZATION request. and it looks like memory contents might get dumped into the log too 🤔

PHP Version

PHP 8.3.10

Operating System

debian

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions