php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79040 Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Submitted: 2019-12-27 19:17 UTC Modified: 2019-12-30 11:25 UTC
From: ASchmidt at Anamera dot net Assigned: cmb (profile)
Status: Closed Package: opcache
PHP Version: 7.3.13 OS: Win x64 IIS
Private report: No CVE-ID: None
 [2019-12-27 19:17 UTC] ASchmidt at Anamera dot net
Description:
------------
Prior to upgrading from 7.3.12 to 7.3.13, OpCache had been functioning (incl. the previous 7.3.x versions).

After installing 7.3.13 (even after reboot), the following messages are now logged:

"Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)"

PHPinfo reports:

Zend OPcache
Opcode Caching = Up and Running 
Optimization = Enabled 
SHM Cache = Disabled 
File Cache = Enabled 
Startup = OK 

opcache.file_cache = C:\Windows\Temp\PHP\OpCache
opcache.file_cache_fallback = 1
opcache.file_cache_only = 0

opcache_get_status() reports:

array (size=3)
  'opcache_enabled' => false
  'file_cache' => 'C:\Windows\Temp\PHP\OpCache'
  'file_cache_only' => true

php.ini contains:

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=3907
opcache.revalidate_freq=30
opcache.enable_file_override=1
opcache.error_log = "C:\Logfiles\PHP\x64_OPcache.log"
opcache.log_verbosity_level=2
opcache.file_cache=C:\Windows\Temp\PHP\OpCache
opcache.file_update_protection=10 



Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-12-27 19:54 UTC] requinix@php.net
And what if you set file_cache_only=1?
 [2019-12-27 20:53 UTC] ASchmidt at Anamera dot net
>> And what if you set file_cache_only=1? <<

As expected, if memory caching is disabled from the onset, then there are no error messages about it being disabled dynamically due to ASLR !?
 [2019-12-27 21:24 UTC] requinix@php.net
Right.

What are you asking for here? To disable the warning on Windows because it'll never work anyways? Unless ASLR is disabled, but people shouldn't do that.
 [2019-12-27 21:29 UTC] ASchmidt at Anamera dot net
I don't understand - there was NO problem with 7.3.12 and prior versions - no warning, and the OpCache GUI never complained about memory stats not existing etc.?
 [2019-12-27 21:42 UTC] requinix@php.net
Ah. What you're seeing is the result of a fix for 7.4.0 that was backported to 7.3.13:

https://www.php.net/ChangeLog-7.php#7.3.13
> Fixed potential ASLR related invalid opline handler issues
 [2019-12-27 22:24 UTC] cmb@php.net
Well, the file cache fallback due to ASLR *can* happen without
that fix (I've rarely, if ever, seen it on x64, though, but
several times on x86).  Otherwise we would not recommend to enable
file_cache_fallback.  And while that "fix" (actually, it's more a
mitigation) increases the likelyhood of the fallback happening, it
it supposed to prevent worse issues.

So, did you experience segfaults or strange application behavior
occassionally before the update to 7.3.13?  And would it help to
reboot the machine, or running fewer instances of php-cgi.exe?

And if you can reproduce that fallback occuring somewhat reliably,
how many php-cgi.exe instances would be affected?  At least one
(but possibly several) may use the shared memory cache, and only
some may fall back to the file cache.  Also please look for the
file whose name starts with ZendOPcache.MemoryBase (and is
followed by two MD5 hashes separated by @ signs) in %TEMP%; there
may be several, since each OPcache instance creates such a file.
The first line of the file contains the base address of the shared
memory, the second line (only there as of PHP 7.3.13) the address
of the execute_ex() function.  Could be interesting to compare the
values of more or less successful OPcache caching after server
restarts (and maybe reboots).
 [2019-12-29 15:46 UTC] ASchmidt at Anamera dot net
Yes - I can produce the fall-back consistently.

Just in case my environment/configuration is relevant to the behavior, "sys_temp_dir" is not set in php.ini, so PHP will use the temp directory passed down from the environment, which effects where ZendOPcache.MemoryBase is located for a particular instance. However opcache.file_cache is set, so all the file caches are centralized.

My sequence of events is always:

- Reboot server
- a Windows service starts, launching a permanent CLI "php.exe" instance.
- I run a manual CLI "php.exe" instance, using the same Windows User, to obtain phpinfo for the command line environment.

No log entries up to that point, phpinfo confirms OPcache working for PHP CLI.

- Open a web page on IIS Site #1 (the browser client will cause multiple secondary resources to be served from other PHP scripts)
- There will be a ASLR log entry for each php-cgi instance.

phpinfo for that web site indicates SHM Cache is DISabled.

Wait until php-cgi instances have shut down (now only the CLI php.exe from the service is still running)

- Open equivalent web page on IIS Site #2 
- There will be a ASLR log entry for each of the newly launched php-cgi instance.

phpinfo for that web site indicates SHM Cache is DISabled.


Now here details showing one test sequence, incl. effected OPcache files and content (incl. their location and access timestamps) you inquired about:

09:18 
- server reboot. 
- CLI for Windows Service starts: php.exe, process #340
- ZendOPcache is accessed in that users "temp" folder: C:\Users\IUSR_Workgroup\AppData\Local\Temp\ZendOPcache.MemoryBase@IUSR_Workgroup@33bdc471edd0e4b556ffbde3f16192f4
Content = 
0000100000000000
00007FF9359D8AB0

09:31 
- run CLI from console to obtain phpinfo, impersonating same user ID
- ZendOPcache is accessed in that users "temp" folder: C:\Users\IUSR_Workgroup\AppData\Local\Temp\ZendOPcache.MemoryBase@IUSR_Workgroup@33bdc471edd0e4b556ffbde3f16192f4
Content identical =
0000100000000000
00007FF9359D8AB0

PHPinfo confims working OPcache

Zend OPcache

Opcode Caching => Up and Running
Optimization => Enabled
SHM Cache => Enabled
File Cache => Enabled
Startup => OK

Shared memory model => win32
Cache hits => 1
Cache misses => 0
Used memory => 16965720
Free memory => 251469736
Wasted memory => 0
Interned Strings Used memory => 385920
Interned Strings Free memory => 12196544
Cached scripts => 1
Cached keys => 1
Max keys => 3907
OOM restarts => 0
Hash keys restarts => 0
Manual restarts => 0


Note: NO log entries thus far!

09:42
- request web page on IIS Site 1
- in this case, 9 php-cgi instances are launched. Each one produces the ASLR log entry:
Sun Dec 29 09:41:55 2019 (2880): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:02 2019 (852): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:11 2019 (248): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:11 2019 (2580): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:11 2019 (1488): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:11 2019 (2744): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:12 2019 (2492): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:12 2019 (1168): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:42:12 2019 (2592): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)

- All 9 instances are using the file cache:
C:\Windows\Temp\PHP\OpCache\60b1385bb59ac949ca08e42b215b571d\33bdc471edd0e4b556ffbde3f16192f4\...

- A different ZendOPcache.MemoryBase is accessed at the Temp folder associated with this IIS application pool: C:\Windows\Temp\ZendOPcache.MemoryBase@IUSR_Workgroup@33bdc471edd0e4b556ffbde3f16192f4
Content DIFFERENT than the CLI one =
0000100000000000
00007FFA55858AB0

09:53
- previous php-cgi instances have vanished.
- request equivalent web page, but on IIS Site 2
- in this case, 2 php-cgi instances are launched (process #1572 + 2824). Each one produces the ASLR log entry:
Sun Dec 29 09:53:23 2019 (2824): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)
Sun Dec 29 09:53:34 2019 (1572): Warning Opcode handlers are unusable due to ASLR (fall-back to file cache)

- The IIS specific ZendOPcache.MemoryBase is accessed at the Temp folder associated with this IIS application pool: C:\Windows\Temp\ZendOPcache.MemoryBase@IUSR_Workgroup@33bdc471edd0e4b556ffbde3f16192f4
Content DIFFERENT than the CLI one, but still the same as with Site #1 from 10 minutes earlier
0000100000000000
00007FFA55858AB0

- PHPinfo for web site:
Opcode Caching  => Up and Running 
Optimization  => Enabled 
SHM Cache => Disabled 
File Cache => Enabled 
Startup => OK
 [2019-12-29 15:50 UTC] ASchmidt at Anamera dot net
>> the result of a fix for 7.4.0 that was backported to 7.3.13 <<

Correct, that's what I saw in the change log - which is why I'm reporting that (at least in my case), that "fix" broke something. OPcache will work for a command line php.exe instance, but will fail for any and all php-cgi.exe instances, the moment the first IIS web page is requested.
 [2019-12-29 23:28 UTC] nikic@php.net
-Assigned To: +Assigned To: cmb
 [2019-12-29 23:28 UTC] nikic@php.net
So, I believe the new check correctly detects a problem here -- in this case it's not even related to ASLR: php-cli and php-cgi are different binaries with different memory layout, so files cached based on one will certainly not be compatible with the other. Most likely you never actually saw issues related to this, because you did not access any files cached via php-cli with php-cgi or vice versa.

However, I think that the actual bug here is the fact that we try to share a cache between php-cli and php-cgi (or two separate SAPIs more generally) in the first place, which can't really work. While on other systems this is prevented by the fork model, on Windows we should be hashing the SAPI into the system ID (or whatever the Windows specific thing is) to make sure these receive separate caches (we should take care to allow sharing the file cache though).
 [2019-12-30 03:54 UTC] ASchmidt at Anamera dot net
Based on your analysis, I rebooted the server after setting opcache.enable_cli = 0.

Naturally, now the background processing of the Windows service php.cgi instance is not being cached at all; however, the two IIS sites handling real-time processing no longer log errors, and the IIS phpinfo lists OPcache being active.

I assume that supports your theory that OPcache requires additional consideration to correctly support Windows systems having CLI and IIS scripts.
 [2019-12-30 11:25 UTC] cmb@php.net
-Status: Assigned +Status: Analyzed
 [2019-12-30 11:25 UTC] cmb@php.net
Thanks everyone!  The problem is now pretty clear.
 [2019-12-30 11:27 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79040: Warning Opcode handlers are unusable due to ASLR
On GitHub:  https://github.com/php/php-src/pull/5038
Patch:      https://github.com/php/php-src/pull/5038.patch
 [2019-12-30 14:19 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0cecf83b264cbbb5683ab8a843cc4a4d9c294644
Log: Fix #79040: Warning Opcode handlers are unusable due to ASLR
 [2019-12-30 14:19 UTC] cmb@php.net
-Status: Analyzed +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 28 09:01:28 2024 UTC