1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.2' into PHP-8.3

* PHP-8.2:
  Fix GH-11078: PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors
This commit is contained in:
Niels Dossche
2024-06-10 19:39:25 +02:00
6 changed files with 88 additions and 2 deletions

4
NEWS
View File

@@ -60,6 +60,10 @@ PHP NEWS
. Fixed bug GH-14290 (Member access within null pointer in extension spl).
(nielsdos)
- Streams:
. Fixed bug GH-11078 (PHP Fatal error triggers pointer being freed was not
allocated and malloc: double free for ptr errors). (nielsdos)
06 Jun 2024, PHP 8.3.8
- CGI:

View File

@@ -750,6 +750,38 @@ static ZEND_FUNCTION(zend_test_set_fmode)
}
#endif
static ZEND_FUNCTION(zend_test_cast_fread)
{
zval *stream_zv;
php_stream *stream;
FILE *fp;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_RESOURCE(stream_zv);
ZEND_PARSE_PARAMETERS_END();
php_stream_from_zval(stream, stream_zv);
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS) == FAILURE) {
return;
}
size_t size = 10240; /* Must be large enough to trigger the issue */
char *buf = malloc(size);
bool bail = false;
zend_try {
(void) !fread(buf, 1, size, fp);
} zend_catch {
bail = true;
} zend_end_try();
free(buf);
if (bail) {
zend_bailout();
}
}
static zend_object *zend_test_class_new(zend_class_entry *class_type)
{
zend_object *obj = zend_objects_new(class_type);

View File

@@ -250,6 +250,9 @@ function zend_test_override_libxml_global_state(): void {}
#if defined(PHP_WIN32)
function zend_test_set_fmode(bool $binary): void {}
#endif
/** @param resource $stream */
function zend_test_cast_fread($stream): void {}
}
namespace ZendTestNS {

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 4d9128205072443957f6229e09153a04c59cce74 */
* Stub hash: 98329c979738792b2fc672d5b5c5a4b5dc0271f4 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@@ -150,6 +150,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_set_fmode, 0, 1, IS_VO
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_cast_fread, 0, 1, IS_VOID, 0)
ZEND_ARG_INFO(0, stream)
ZEND_END_ARG_INFO()
#define arginfo_ZendTestNS2_namespaced_func arginfo_zend_test_is_pcre_bundled
#define arginfo_ZendTestNS2_namespaced_deprecated_func arginfo_zend_test_void_return
@@ -275,6 +279,7 @@ static ZEND_FUNCTION(zend_test_is_pcre_bundled);
#if defined(PHP_WIN32)
static ZEND_FUNCTION(zend_test_set_fmode);
#endif
static ZEND_FUNCTION(zend_test_cast_fread);
static ZEND_FUNCTION(ZendTestNS2_namespaced_func);
static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func);
static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func);
@@ -351,6 +356,7 @@ static const zend_function_entry ext_functions[] = {
#if defined(PHP_WIN32)
ZEND_FE(zend_test_set_fmode, arginfo_zend_test_set_fmode)
#endif
ZEND_FE(zend_test_cast_fread, arginfo_zend_test_cast_fread)
ZEND_NS_FALIAS("ZendTestNS2", namespaced_func, ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func)
ZEND_NS_DEP_FALIAS("ZendTestNS2", namespaced_deprecated_func, ZendTestNS2_namespaced_deprecated_func, arginfo_ZendTestNS2_namespaced_deprecated_func)
ZEND_NS_FALIAS("ZendTestNS2", namespaced_aliased_func, zend_test_void_return, arginfo_ZendTestNS2_namespaced_aliased_func)

View File

@@ -0,0 +1,34 @@
--TEST--
GH-11078 (PHP Fatal error triggers pointer being freed was not allocated and malloc: double free for ptr errors)
--EXTENSIONS--
zend_test
--SKIPIF--
<?php
if (getenv('USE_ZEND_ALLOC') === '0') die('skip Zend MM disabled');
if (PHP_OS_FAMILY === 'Windows') die('skip Windows does not support generic stream casting');
?>
--FILE--
<?php
const MEM = 32 * 1024 * 1024;
ini_set('memory_limit', MEM);
class CrashingFifo {
public $context;
function stream_open($path, $mode, $options, &$opened_path): bool {
return true;
}
function stream_read(int $count): false|string|null {
return str_repeat('x', MEM);
}
}
stream_register_wrapper('fifo', CrashingFifo::class);
$readStream = fopen('fifo://1', 'r');
zend_test_cast_fread($readStream);
?>
--EXPECTF--
Fatal error: Allowed memory size of %d bytes exhausted %s

View File

@@ -46,7 +46,14 @@ typedef struct {
FILE *fopencookie(void *cookie, const char *mode, COOKIE_IO_FUNCTIONS_T *funcs)
{
return funopen(cookie, funcs->reader, funcs->writer, funcs->seeker, funcs->closer);
FILE *file = funopen(cookie, funcs->reader, funcs->writer, funcs->seeker, funcs->closer);
if (file) {
/* Buffering of FILE handles is stateful.
* A bailout during these can corrupt the state of the FILE handle
* and cause memory corruption errors. See GH-11078. */
setvbuf(file, NULL, _IONBF, 0);
}
return file;
}
# define HAVE_FOPENCOOKIE 1
# define PHP_EMULATE_FOPENCOOKIE 1