php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48633 str_pad() with giant lenth value and no memory limit infinite-loops or crashes
Submitted: 2009-06-22 00:09 UTC Modified: 2010-11-19 14:18 UTC
From: gwynne@php.net Assigned: iliaa (profile)
Status: Closed Package: Reproducible crash
PHP Version: 5.*, 6SVN (2009-07-25) OS: Darwin9 (MacOS X 10.5)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: gwynne@php.net
New email:
PHP Version: OS:

 

 [2009-06-22 00:09 UTC] gwynne@php.net
Description:
------------
Calling str_pad($anything, PHP_INT_MAX) causes one of four symptoms:

1) If memory_limit is set below 2GB, a fatal error is thrown saying the memory limit is exhausted with an attempt to allocate 2GB. This appears to be the expected result.
2) If memory_limit is set above 2GB, or is unset, PHP (in or out of GDB) enters a massive CPU-eating swap-file-smashing loop.
3) If PHP is being run under valgrind, PHP exits quickly with a memory allocation failure because valgrind's malloc() replacement refuses the "nonsense" allocation request.
4) If PHP is being run under valgrind *and* run-tests.php, PHP crashes with a NULL pointer reference.

This is caused by two problems in the str_pad code:

1) The value of num_pad_chars is not bounds-checked in ext/standard/string.c:4830
2) The return value of emalloc() is not checked for NULL on the same line.

Reproduce code:
---------------
1) $ sapi/cli/php ext/standard/tests/string/str_pad_variation5.phpt

2) $ sapi/cli/php -dmemory_limit=1 ext/standard/tests/string/str_pad_variation5.phpt

3) $ valgrind sapi/cli/php -dmemory_limit=1 ext/standard/tests/string/str_pad_variation5.phpt

4) $ PHP_TEST_EXECUTABLE=`pwd`/sapi/cli/php sapi/cli/php run-tests.php -m ext/standard/tests/string/str_pad_variation5.phpt

Expected result:
----------------
In all cases, str_pad() should recognize that its argument is ridiculous and return without trying to make the allocation.

Actual result:
--------------
1)
*** Testing str_pad() function: with large value for for 'pad_length' argument ***

Fatal error: Allowed memory size of 134217728 bytes exhausted at ext/standard/string.c:4830 (tried to allocate 2147483648 bytes) in ext/standard/tests/strings/str_pad_variation5.phpt on line 25

2)
PHP starts running at 100% CPU and eating huge amounts of swap space.

3)
*** Testing str_pad() function: with large value for for 'pad_length' argument ***
==31081== Warning: silly arg (-2147221504) to malloc()

Fatal error: Out of memory (allocated 524288) at ext/standard/string.c:4830 (tried to allocate 2147483648 bytes) in ext/standard/tests/strings/str_pad_variation5.phpt on line 25

4)
==31145== Warning: silly arg (-2147483648) to malloc()
==31145== Invalid write of size 1
==31145==    at 0x823B13: memcpy (mc_replace_strmem.c:482)
==31145==    by 0x2B3F92: zif_str_pad (string.c:4855)
==31145==    by 0x3E2D98: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:313)
==31145==    by 0x3E9151: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:1601)
==31145==    by 0x3E1B59: execute (zend_vm_execute.h:104)
==31145==    by 0x3AE947: zend_execute_scripts (zend.c:1188)
==31145==    by 0x31E6CC: php_execute_script (main.c:2196)
==31145==    by 0x499E5F: main (php_cli.c:1188)
==31145==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==31145==
==31145== Process terminating with default action of signal 10 (SIGBUS)
==31145==  Non-existent physical address at address 0x0
==31145==    at 0x823B13: memcpy (mc_replace_strmem.c:482)
==31145==    by 0x2B3F92: zif_str_pad (string.c:4855)
==31145==    by 0x3E2D98: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:313)
==31145==    by 0x3E9151: ZEND_DO_FCALL_SPEC_CONST_HANDLER (zend_vm_execute.h:1601)
==31145==    by 0x3E1B59: execute (zend_vm_execute.h:104)
==31145==    by 0x3AE947: zend_execute_scripts (zend.c:1188)
==31145==    by 0x31E6CC: php_execute_script (main.c:2196)
==31145==    by 0x499E5F: main (php_cli.c:1188)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-07-17 17:40 UTC] jani@php.net
Does this happen with PHP_5_2 and/or HEAD? (if so, update the version 
properly)
 [2009-07-18 01:41 UTC] gwynne@php.net
Yes, it happens in all three branches.
 [2010-05-19 15:57 UTC] mike@php.net
-Status: Open +Status: Feedback
 [2010-05-19 15:57 UTC] mike@php.net
Doesn't do anything harmful for me.
 [2010-08-09 01:34 UTC] felipe@php.net
-Status: Feedback +Status: Assigned -Assigned To: +Assigned To: iliaa
 [2010-08-09 01:34 UTC] felipe@php.net
It looks be fixed with the Ilia's patch.
 [2010-11-19 14:18 UTC] iliaa@php.net
-Status: Assigned +Status: Closed
 [2010-11-19 14:18 UTC] iliaa@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 15 01:01:35 2025 UTC