php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79825 opcache.file_cache causes SIGSEGV when custom opcode handlers changed
Submitted: 2020-07-09 22:53 UTC Modified: 2020-07-10 07:14 UTC
From: sammyk@php.net Assigned:
Status: Closed Package: opcache
PHP Version: 7.4.8 OS: Any
Private report: No CVE-ID: None
 [2020-07-09 22:53 UTC] sammyk@php.net
Description:
------------
When `opcache.file_cache` is used, the memory address of the opcode handlers are serialized into the op_array that is stored in the second-level cache files. This includes custom opcode handlers provided by extensions.

On process restart, the cached files are loaded into memory on the next request. The issue is that after a process restart, the extensions that were present when the op_array was serialized are not guaranteed to be there on restart. Or a user could have upgraded an extension and it hooks different opcodes than the previous version. If either of these are the case, the request will cause a SIGSEGV when it tries to access the address of the custom opcode handler that no longer exists.

To repro this issue:

1. Install an extension that provides custom opcode handlers
2. Start up a process with `opcache.file_cache` set
3. Run a request that emits an opcode hooked by the installed extension
4. Then disable the extension, restart, and run the request again

Here's an example using Xdebug and the test script below.

```bash
$ mkdir tmp && php-cgi \
    -d opcache.file_cache=$(pwd)/tmp \
    -d xdebug.scream=1 \
    -f bug.php

# Remove Xdebug before running

$ php-cgi \
    -d opcache.file_cache=$(pwd)/tmp \
    -f bug.php
Segmentation fault (core dumped)

$ gdb php-cgi core
[...]
Core was generated by `php-cgi -d opcache.file_cache=/home/circleci/app/tmp -f bug.php'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x0000559d9da3bdf0 in ZEND_USER_OPCODE_SPEC_HANDLER ()
    at /usr/local/src/php/Zend/zend_vm_execute.h:2637
#2  0x0000559d9da991ef in execute_ex (ex=0x7f1188014020)
    at /usr/local/src/php/Zend/zend_vm_execute.h:53902
#3  0x0000559d9da9d18d in zend_execute (op_array=0x7f1188065000, return_value=0x0)
    at /usr/local/src/php/Zend/zend_vm_execute.h:57922
#4  0x0000559d9d9c9f01 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/local/src/php/Zend/zend.c:1666
#5  0x0000559d9d93328a in php_execute_script (primary_file=0x7ffe9fb82610)
    at /usr/local/src/php/main/main.c:2617
#6  0x0000559d9daa6e31 in main (argc=5, argv=0x7ffe9fb82858)
    at /usr/local/src/php/sapi/cgi/cgi_main.c:2556
(gdb)
```

Test script:
---------------
<?php

# xdebug.scream=1 overloads ZEND_BEGIN_SILENCE & ZEND_END_SILENCE
# @see https://github.com/xdebug/xdebug/blob/f83939c/src/develop/develop.c#L79-L81
@var_dump('foo');


Expected result:
----------------
string(3) "foo"

Actual result:
--------------
Segmentation fault (core dumped)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-10 07:15 UTC] cmb@php.net
This is basically the same issue than bug #75886.  See also
<https://externals.io/message/107773>.
 [2020-09-09 19:48 UTC] sammyk@php.net
Automatic comment on behalf of sammyk
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2d4aa1ef3d04ec85a15ae426ffdaa4f2fb0f1556
Log: Fix #79825: opcache.file_cache causes SIGSEGV with custom opcode handlers
 [2020-09-09 19:48 UTC] sammyk@php.net
-Status: Open +Status: Closed
 [2020-09-09 20:00 UTC] sammyk@php.net
Automatic comment on behalf of sammyk
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2d4aa1ef3d04ec85a15ae426ffdaa4f2fb0f1556
Log: Fix #79825: opcache.file_cache causes SIGSEGV with custom opcode handlers
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 21 09:01:23 2020 UTC