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

Merge branch 'PHP-8.3'

* PHP-8.3:
  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:40:03 +02:00
5 changed files with 84 additions and 2 deletions

View File

@@ -774,6 +774,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

@@ -281,6 +281,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: 35c11b9781669cff5ad72aa78b9b3732f7b827f1 */
* Stub hash: 810a94e09724a27d46c99495593da999cfc46243 */
ZEND_STATIC_ASSERT(PHP_VERSION_ID >= 80000, "test_arginfo.h only supports PHP version ID 80000 or newer, "
"but it is included on an older PHP version");
@@ -158,6 +158,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
@@ -283,6 +287,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);
@@ -379,6 +384,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)
#if (PHP_VERSION_ID >= 80400)
ZEND_RAW_FENTRY(ZEND_NS_NAME("ZendTestNS2", "namespaced_func"), zif_ZendTestNS2_namespaced_func, arginfo_ZendTestNS2_namespaced_func, 0, NULL, NULL)
#else

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