From e58628469911bf4558d54875bd9c727975115aee Mon Sep 17 00:00:00 2001 From: Edmond <1571649+edmonddantes@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:55:53 +0000 Subject: [PATCH] Fix use-after-free when an error handler removes a failing zlib.inflate filter The filter raised its notice and then reset its state; an error handler that removed the filter had freed that state by then. --- ..._inflate_error_handler_removes_filter.phpt | 30 +++++++++++++++++++ ext/zlib/zlib_filter.c | 3 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ext/zlib/tests/zlib_filter_inflate_error_handler_removes_filter.phpt diff --git a/ext/zlib/tests/zlib_filter_inflate_error_handler_removes_filter.phpt b/ext/zlib/tests/zlib_filter_inflate_error_handler_removes_filter.phpt new file mode 100644 index 000000000000..ee5bab1052fc --- /dev/null +++ b/ext/zlib/tests/zlib_filter_inflate_error_handler_removes_filter.phpt @@ -0,0 +1,30 @@ +--TEST-- +zlib.inflate filter removed by the error handler of its own notice +--EXTENSIONS-- +zlib +--FILE-- + +--EXPECT-- +fwrite(): zlib: data error +bool(true) +bool(false) +fread(): zlib: data error +bool(true) +bool(false) +Done diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c index e5491afec391..85711be8caa1 100644 --- a/ext/zlib/zlib_filter.c +++ b/ext/zlib/zlib_filter.c @@ -90,11 +90,12 @@ static php_stream_filter_status_t php_zlib_inflate_filter( exit_status = PSFS_PASS_ON; } else if (status != Z_OK && status != Z_BUF_ERROR) { /* Something bad happened */ - php_error_docref(NULL, E_NOTICE, "zlib: %s", zError(status)); php_stream_bucket_delref(bucket); /* reset these because despite the error the filter may be used again */ data->strm.next_in = data->inbuf; data->strm.avail_in = 0; + /* Last: an error handler may remove this filter and free data. */ + php_error_docref(NULL, E_NOTICE, "zlib: %s", zError(status)); return PSFS_ERR_FATAL; } desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */