Bug 1305504

Summary: php: Large negative number as input to round() causes segfault on 64-bit builds
Product: [Other] Security Response Reporter: Adam Mariš <amaris>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED NOTABUG QA Contact:
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: unspecifiedCC: abhgupta, dmcphers, fedora, jialiu, jokerman, jorton, kseifried, lmeyer, mmaslano, mmccomas, rcollet, tiwillia, webstack-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: php 5.6.18, php 7.0.3 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-10-12 11:57:49 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1305565    
Bug Blocks: 1305564    

Description Adam Mariš 2016-02-08 12:53:19 UTC
It was reported that Supplying a large negative number as the second parameter to round() reliably produces a segmentation fault on 64-bit builds.

Upstream bug:

https://bugs.php.net/bug.php?id=71201

Upstream patch:

https://git.php.net/?p=php-src.git;a=commit;h=0d822f6df946764f3f0348b82efae2e1eaa83aa0

Comment 1 Adam Mariš 2016-02-08 15:13:45 UTC
Created php tracking bugs for this issue:

Affects: fedora-all [bug 1305565]

Comment 2 Remi Collet 2016-02-08 15:21:19 UTC
Not secutity (need specially crafted code)

Comment 3 Tomas Hoger 2016-10-12 11:57:49 UTC
(In reply to Remi Collet from comment #2)
> Not secutity (need specially crafted code)

It also does not seem to be reproducible with our PHP builds.  Additionally, the crash backtrace in the upstream bug suggests some compiler / optimization issue.  Crash happens in the php_intpow10() function:

static inline double php_intpow10(int power) {
	static const double powers[] = {
		1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,
		1e8,  1e9,  1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
		1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};

	/* Not in lookup table */
	if (power < 0 || power > 22) {
		return pow(10.0, (double)power);
	}
	return powers[power];
}

According to the backtrace, the function is called with power=-2147483648.  Hence the 'return powers[power]' where crash is reported should not be reached and the function should rather call 'return pow(10.0, (double)power)'.