Skip to content

Commit 15f4dee

Browse files
committed
Add a unlink check for php_stream_bucket_unlink
This is in the same spirit as #13943: low-hanging, not in a hot-path, trivial, removing a limited-linear-write → arbitrary-write primitive, … moreover, given how many filters are available, having some low-hanging hardening there shouldn't hurt. cc @arnaud-lb
1 parent 8cf8751 commit 15f4dee

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

main/streams/filter.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,33 @@
2222
#include <stddef.h>
2323
#include <fcntl.h>
2424

25+
#ifndef ZEND_HEAP_CHECK
26+
# define ZEND_HEAP_CHECK(condition, message) do { \
27+
if (UNEXPECTED(!(condition))) { \
28+
zend_heap(message); \
29+
} \
30+
} while (0)
31+
#endif
32+
2533
#include "php_streams_int.h"
2634

2735
/* Global filter hash, copied to FG(stream_filters) on registration of volatile filter */
2836
static HashTable stream_filters_hash;
2937

38+
static ZEND_COLD ZEND_NORETURN void zend_heap(const char *message)
39+
{
40+
fprintf(stderr, "%s\n", message);
41+
/* See http://support.microsoft.com/kb/190351 */
42+
#ifdef ZEND_WIN32
43+
fflush(stderr);
44+
#endif
45+
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
46+
kill(getpid(), SIGSEGV);
47+
#endif
48+
abort();
49+
}
50+
51+
3052
/* Should only be used during core initialization */
3153
PHPAPI HashTable *php_get_stream_filters_hash_global(void)
3254
{
@@ -192,11 +214,13 @@ PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_str
192214
PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket)
193215
{
194216
if (bucket->prev) {
217+
ZEND_HEAP_CHECK(bucket->prev->next == bucket, "Stream bucket list corruption.");
195218
bucket->prev->next = bucket->next;
196219
} else if (bucket->brigade) {
197220
bucket->brigade->head = bucket->next;
198221
}
199222
if (bucket->next) {
223+
ZEND_HEAP_CHECK(bucket->next->prev == bucket, "Stream bucket list corruption.");
200224
bucket->next->prev = bucket->prev;
201225
} else if (bucket->brigade) {
202226
bucket->brigade->tail = bucket->prev;

0 commit comments

Comments
 (0)