php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78654 Incorrectly computed opcache checksum on files with non-ascii characters
Submitted: 2019-10-09 07:52 UTC Modified: 2019-10-17 07:37 UTC
From: mhagstrand at gmail dot com Assigned: nikic (profile)
Status: Closed Package: opcache
PHP Version: 7.2.23 OS:
Private report: No CVE-ID: None
 [2019-10-09 07:52 UTC] mhagstrand at gmail dot com
Description:
------------
The checksum can be incorrectly computed when a file to be cached contains non-ascii characters.  When the opcache computes the checksum before it writes the file it chains together two calls to zend_adler32. 

https://github.com/php/php-src/blob/PHP-7.2.24/ext/opcache/zend_file_cache.c#L870

When the bin file containing the opcache is loaded it computes the checksum with a single call to zend_adler32.

https://github.com/php/php-src/blob/PHP-7.2.24/ext/opcache/zend_file_cache.c#L1461

The zend_adler32 function uses signed chars instead of unsigned chars. As a result non-ascii characters can have negative values. This means checksum is incorrectly computed and chained calls can result in different values than a single call to zend_adler32.

https://github.com/php/php-src/blob/PHP-7.2.24/ext/opcache/zend_accelerator_util_funcs.c#L738

Test script:
---------------
Ini settings
opcache.enable=1
opcache.enable_cli=1
opcache.file_cache=/tmp
opcache.log_verbosity_level=3

<?php
$mbChars = ['°','₀','۰','0','¹','₁','۱','1','²','₂','۲','2','³','₃','۳','3','⁴','₄','۴','٤',
                '4','⁵','₅','۵','٥','5','⁶','₆','۶','٦','6','⁷','₇','۷','7','⁸','₈','۸','8',
                '⁹','₉','۹','9','à','á','ả','ã','ạ','ă','ắ','ằ','ẳ','ẵ','ặ','â','ấ','ầ','ẩ','ẫ',
                'ᾆ','ᾇ','ὰ','ά','ᾰ','ᾱ','ᾲ','ᾳ','ᾴ','ᾶ','ᾷ','а','ﺃ','အ','ာ','ါ','ǻ','ǎ','ª','ა','अ
                ','ﺍ','a','ä','б','β','ﺏ','ဗ','ბ','b','ç','ć','č','ĉ','ċ','c','ď','ð','đ','ƌ',
                'ȡ','ɖ','ɗ','ᵭ','ᶁ','ᶑ','д','δ','ﺩ','ﺽ','ဍ','ဒ','დ','d','é','è','ẻ','ẽ','ẹ','ê',
                'ľ','ĺ','ļ','ŀ','л','λ','ﻝ','လ','ლ','l','м','μ','ﻡ','မ','მ','m','ñ','ń','ň',
                'ộ','ơ','ớ','ờ','ở','ỡ','ợ','ø','ō','ő','ŏ','ο','ὀ','ὁ','ὂ','ὃ','ὄ','ὅ','ὸ',
                'ũ','ụ','ư','ứ','ừ','ử','ữ','ự','û','ū','ů','ű','ŭ','ų','µ','у','ဉ','ု','ူ','ǔ',
                'Ĩ','Ị','Î','Ï','Ī','Ĭ','Į','İ','Ι','Ί','Ϊ','Ἰ','Ἱ','Ἳ','Ἴ','Ἵ','Ἶ','Ἷ','Ῐ','Ῑ',
                'Ὶ','Ί','И','І','Ї','Ǐ','ϒ','I','J','К','Κ','K','Ĺ','Ł','Л','Λ','Ļ','Ľ','Ŀ',
		'Ὃ','Ὄ','Ὅ','Ὸ','Ό','О','Θ','Ө','Ǒ','Ǿ','O','Ö','П','Π','P','Q','Ř','Ŕ','Р',
                'Ÿ','Ῠ','Ῡ','Ὺ','Ύ','Ы','Й','Υ','Ϋ','Ŷ','Y','Ź','Ž','Ż','З','Ζ','Z','Æ','Ǽ',
                'Ч','Ђ','Џ','Ĝ','Ĥ','IJ','Ĵ','Х','Љ','Њ','Œ','Ψ','Ш','Щ','ẞ','Þ','Ц','Я','Ю',
                'Ж',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','ᅠ'];

echo "Hello World\n";
?>


Expected result:
----------------
When the opcache is loaded from a file the checksum in the file matches the computed checksum. No warning about a corrupted file in the logs.

Actual result:
--------------
In the opcache log the following warning shows up if the opcache bin file exists.

Warning corrupted file '/tmp/285d13c8bcb81a2cb747f9609f2e9b08/opt/php-src/ext/opcache/tests/adler32_checksum.php.bin'

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-09 08:24 UTC] mhagstrand at gmail dot com
The following pull request has been associated:

Patch Name: Fix checksum calculation for opcache
On GitHub:  https://github.com/php/php-src/pull/4804
Patch:      https://github.com/php/php-src/pull/4804.patch
 [2019-10-17 07:37 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Dec 09 06:01:25 2019 UTC