Skip to content

Commit 6f64a31

Browse files
committed
Detect heap freelist corruption
1 parent 44c199c commit 6f64a31

11 files changed

+371
-21
lines changed

Zend/zend.c

+7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
9494
ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
9595
ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL;
9696
ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
97+
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes)(void *bytes, size_t size, char *errstr, size_t errstr_size) = NULL;
98+
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes_insecure)(zend_utility_random_bytes_insecure_state *state, void *bytes, size_t size) = NULL;
9799

98100
/* This callback must be signal handler safe! */
99101
void (*zend_on_timeout)(int seconds);
@@ -912,6 +914,11 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
912914
php_win32_cp_set_by_id(65001);
913915
#endif
914916

917+
/* Set up early utility functions. zend_mm depends on
918+
* zend_random_bytes_insecure */
919+
zend_random_bytes = utility_functions->random_bytes_function;
920+
zend_random_bytes_insecure = utility_functions->random_bytes_insecure_function;
921+
915922
start_memory_manager();
916923

917924
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */

Zend/zend.h

+15
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ struct _zend_class_entry {
234234
} info;
235235
};
236236

237+
typedef union {
238+
zend_max_align_t align;
239+
uint64_t opaque[5];
240+
} zend_utility_random_bytes_insecure_state;
241+
237242
typedef struct _zend_utility_functions {
238243
void (*error_function)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
239244
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
@@ -248,6 +253,8 @@ typedef struct _zend_utility_functions {
248253
void (*printf_to_smart_str_function)(smart_str *buf, const char *format, va_list ap);
249254
char *(*getenv_function)(const char *name, size_t name_len);
250255
zend_string *(*resolve_path_function)(zend_string *filename);
256+
zend_result (*random_bytes_function)(void *bytes, size_t size, char *errstr, size_t errstr_size);
257+
zend_result (*random_bytes_insecure_function)(zend_utility_random_bytes_insecure_state *state, void *bytes, size_t size);
251258
} zend_utility_functions;
252259

253260
typedef struct _zend_utility_values {
@@ -340,6 +347,14 @@ extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format
340347
extern void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
341348
extern ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
342349
extern ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
350+
/* Generate 'size' random bytes into 'bytes' with the OS CSPRNG. */
351+
extern ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes)(
352+
void *bytes, size_t size, char *errstr, size_t errstr_size);
353+
/* Generate 'size' random bytes into 'bytes' with a general purpose PRNG (not
354+
* crypto safe). 'state' must be zeroed before the first call and can be reused.
355+
*/
356+
extern ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes_insecure)(
357+
zend_utility_random_bytes_insecure_state *state, void *bytes, size_t size);
343358

344359
/* These two callbacks are especially for opcache */
345360
extern ZEND_API zend_result (*zend_post_startup_cb)(void);

0 commit comments

Comments
 (0)