Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2019-11046: PHP :: Sec Bug #78878 :: Buffer underflow in bc_shift_addsub

In PHP versions 7.2.x below 7.2.26, 7.3.x below 7.3.13 and 7.4.0, PHP bcmath extension functions on some systems, including Windows, can be tricked into reading beyond the allocated space by supplying it with string containing characters that are identified as numeric by the OS but aren’t ASCII numbers. This can read to disclosure of the content of some memory locations.

CVE
#mac#windows#git#php

Sec Bug #78878

Buffer underflow in bc_shift_addsub

Submitted:

2019-11-28 15:03 UTC

Modified:

2019-12-16 19:01 UTC

From:

thomas-josef dot riedmaier at siemens dot com

Assigned:

stas (profile)

Status:

Closed

Package:

BC math related

PHP Version:

7.4.0

OS:

Windows

Private report:

No

CVE-ID:

2019-11046

[2019-11-28 15:03 UTC] thomas-josef dot riedmaier at siemens dot com

Description:

When executing the test snippet below, a buffer underflow occurs in bc_shift_addsub.

I theory, bc_shift_addsub’s assert statement would be triggered, but this does not play any role in the official windows release binaries https://windows.php.net/downloads/releases/php-7.4.0-Win32-vc15-x64.zip .

Instead, on our test machines, an ACCESS_VIOLATION is triggered.

Test script:

<?php

print bcmul(²6483605105519922841849335928742092, bcpowmod(2, 65535, -4e-4));

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports

[2019-11-28 16:02 UTC] [email protected]

-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb

[2019-11-28 16:02 UTC] [email protected]

I cannot reproduce the access violation (neither with the given code, nor when I replace the ² with 2, nor when I just remove the ²). And neither does the assertion trigger in a debug build for me (it won’t trigger in release builds anyway).

Could you please fix/clarify the test script?

[2019-11-29 07:37 UTC] thomas-josef dot riedmaier at siemens dot com

I digged a little bit into this and it appears to be a system-dependent problem.

When running the script with Windows7 SP1 or Windows Server 2016 (1607), the script says “Warning: Use of undefined constant �6483605105519922841849335928742092 - assumed '�6483605105519922841849335928742092’” and crashes.

Note the non printable character here.

When running the script with Windows 10 (1809), the scipt says “Warning: Use of undefined constant 6483605105519922841849335928742092 - assumed '6483605105519922841849335928742092’” and does not crash.

Note that there is no unprintable character here.

So it appears to me that depending on the Windows setup, php seem to ignore the '²’, or not. If it is not ignored, an access violation occurs.

[2019-11-29 10:21 UTC] [email protected]

Hmm, pretty strange that the behavior depends on the Windows version, but of course, possible.

Could you please post what you get when running

<?php var_dump(²6483605105519922841849335928742092);

Note that the charset/character encoding may very well matter here.

[2019-11-29 13:05 UTC] thomas-josef dot riedmaier at siemens dot com

C:\Users\IEUser>C:\Users\IEUser\Desktop\php-7.4.0-Win32-vc15-x64\php.exe C:\Users\IEUser\Desktop\text.php

Warning: Use of undefined constant ²6483605105519922841849335928742092 - assumed ‘²6483605105519922841849335928742092’ (this will throw an Error in a future ver sion of PHP) in C:\Users\IEUser\Desktop\text.php on line 3 string(35) “²6483605105519922841849335928742092”

[2019-11-29 13:13 UTC] [email protected]

-Status: Feedback +Status: Open

[2019-11-29 13:13 UTC] [email protected]

Thanks! That proves that the ² is encoded as a single byte (so it’s not any Unicode encoding).

[2019-11-30 11:32 UTC] [email protected]

-Type: Bug +Type: Security -Assigned To: cmb +Assigned To: stas -Private report: No +Private report: Yes

[2019-11-30 11:32 UTC] [email protected]

While I still not have been able to reproduce the access violation, it’s pretty clear that the code may allow for that, because it uses isdigit()[1] which is locale-dependent, to check for digits, but only expects decimal ASCII digits[2]. So depending on the current locale, on char signedness, and perhaps a broken isdigit() implementation, this can lead to all kinds of issues.

Therefore, I’m tentatively re-classifying as security issue.

Suggested patch: https://gist.github.com/cmb69/4796c38a08cb17aef5daaa57bcf75041\. For PHP-7.3+ also PHP-7.3+.patch has to be applied.

Stas, could you please handle it from here? If it’s not security issue, please assign back to me.

[1] https://github.com/php/php-src/blob/php-7.4.0/ext/bcmath/libbcmath/src/str2num.c#L59-L61\ [2] https://github.com/php/php-src/blob/php-7.4.0/ext/bcmath/libbcmath/src/bcmath.h#L61-L64\

[2019-11-30 21:52 UTC] [email protected]

I am not sure I understand the issue completely - let’s say isdigit misclassified the character, what could happen because of that? Why it is different from just having non-digit passed to the function?

[2019-12-01 12:43 UTC] [email protected]

If a non-digit is passed to the function, E_WARNING is raised, and the number is taken as zero. If a digit, which is not an ASCII digit, is passed, it is stored as `digit - '0’` (BCMath stores each decimal digit in a full byte), and as such has a value < 0 or

9; libbcmath expects all bytes to be in range [0,9], though.

[2019-12-16 08:16 UTC] [email protected]

-CVE-ID: +CVE-ID: 2019-11046

[2019-12-16 19:02 UTC] [email protected]

-Status: Assigned +Status: Closed

Related news

CVE-2016-4343: PHP: PHP 7 ChangeLog

The phar_make_dirstream function in ext/phar/dirstream.c in PHP before 5.6.18 and 7.x before 7.0.3 mishandles zero-size ././@LongLink files, which allows remote attackers to cause a denial of service (uninitialized pointer dereference) or possibly have unspecified other impact via a crafted TAR archive.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907