Skip to content

Commit 6434c93

Browse files
committed
Explicitly store real map ptr base
If we only store the biased pointer, the map ptr region will not be recognized as reachable memory by leak checkers. This is primarily problematic for fuzzing, because this is persistent memory that may be reallocated during the request, without being an actual leak. Avoid this by simply storing both the real base pointer of the allocation, as well as the biased base pointer used for accesses.
1 parent 9cd6c57 commit 6434c93

File tree

4 files changed

+36
-32
lines changed

4 files changed

+36
-32
lines changed

Zend/zend.c

+28-20
Original file line numberDiff line numberDiff line change
@@ -704,15 +704,16 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
704704

705705
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
706706
/* Map region is going to be created and resized at run-time. */
707-
ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
707+
compiler_globals->map_ptr_real_base = NULL;
708+
compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
708709
compiler_globals->map_ptr_size = 0;
709710
compiler_globals->map_ptr_last = global_map_ptr_last;
710711
if (compiler_globals->map_ptr_last) {
711712
/* Allocate map_ptr table */
712-
void *base;
713713
compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096);
714-
base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
715-
ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, base);
714+
void *base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
715+
compiler_globals->map_ptr_real_base = base;
716+
compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(base);
716717
memset(base, 0, compiler_globals->map_ptr_last * sizeof(void*));
717718
}
718719
#else
@@ -739,9 +740,10 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
739740
if (compiler_globals->script_encoding_list) {
740741
pefree((char*)compiler_globals->script_encoding_list, 1);
741742
}
742-
if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
743-
free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
744-
ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
743+
if (compiler_globals->map_ptr_real_base) {
744+
free(compiler_globals->map_ptr_real_base);
745+
compiler_globals->map_ptr_real_base = NULL;
746+
compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
745747
compiler_globals->map_ptr_size = 0;
746748
}
747749
}
@@ -972,10 +974,12 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
972974
*/
973975
CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ???
974976
CG(map_ptr_last) = 0;
975-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), pemalloc(CG(map_ptr_size) * sizeof(void*), 1));
977+
CG(map_ptr_real_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1);
978+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
976979
# elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
977980
/* Map region is going to be created and resized at run-time. */
978-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
981+
CG(map_ptr_real_base) = NULL;
982+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL);
979983
CG(map_ptr_size) = 0;
980984
CG(map_ptr_last) = 0;
981985
# else
@@ -1057,10 +1061,11 @@ zend_result zend_post_startup(void) /* {{{ */
10571061
compiler_globals->function_table = NULL;
10581062
free(compiler_globals->class_table);
10591063
compiler_globals->class_table = NULL;
1060-
if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) {
1061-
free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base));
1064+
if (compiler_globals->map_ptr_real_base) {
1065+
free(compiler_globals->map_ptr_real_base);
10621066
}
1063-
ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL);
1067+
compiler_globals->map_ptr_real_base = NULL;
1068+
compiler_globals->map_ptr_base = ZEND_MAP_PTR_BIASED_BASE(NULL);
10641069
if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) {
10651070
compiler_globals_ctor(compiler_globals);
10661071
compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list;
@@ -1117,9 +1122,10 @@ void zend_shutdown(void) /* {{{ */
11171122
ts_free_id(executor_globals_id);
11181123
ts_free_id(compiler_globals_id);
11191124
#else
1120-
if (ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base))) {
1121-
free(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)));
1122-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL);
1125+
if (CG(map_ptr_real_base)) {
1126+
free(CG(map_ptr_real_base));
1127+
CG(map_ptr_real_base) = NULL;
1128+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(NULL);
11231129
CG(map_ptr_size) = 0;
11241130
}
11251131
if (CG(script_encoding_list)) {
@@ -1224,7 +1230,7 @@ ZEND_API void zend_activate(void) /* {{{ */
12241230
init_executor();
12251231
startup_scanner();
12261232
if (CG(map_ptr_last)) {
1227-
memset(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), 0, CG(map_ptr_last) * sizeof(void*));
1233+
memset(CG(map_ptr_real_base), 0, CG(map_ptr_last) * sizeof(void*));
12281234
}
12291235
zend_observer_activate();
12301236
}
@@ -1821,12 +1827,13 @@ ZEND_API void *zend_map_ptr_new(void)
18211827
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
18221828
/* Grow map_ptr table */
18231829
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
1824-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
1830+
CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), CG(map_ptr_size) * sizeof(void*), 1);
1831+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
18251832
#else
18261833
# error "Unknown ZEND_MAP_PTR_KIND"
18271834
#endif
18281835
}
1829-
ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
1836+
ptr = (void**)CG(map_ptr_real_base) + CG(map_ptr_last);
18301837
*ptr = NULL;
18311838
CG(map_ptr_last)++;
18321839
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
@@ -1850,12 +1857,13 @@ ZEND_API void zend_map_ptr_extend(size_t last)
18501857
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
18511858
/* Grow map_ptr table */
18521859
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096);
1853-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
1860+
CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), CG(map_ptr_size) * sizeof(void*), 1);
1861+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
18541862
#else
18551863
# error "Unknown ZEND_MAP_PTR_KIND"
18561864
#endif
18571865
}
1858-
ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last);
1866+
ptr = (void**)CG(map_ptr_real_base) + CG(map_ptr_last);
18591867
memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*));
18601868
CG(map_ptr_last) = last;
18611869
}

Zend/zend_globals.h

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ struct _zend_compiler_globals {
125125
HashTable *memoized_exprs;
126126
int memoize_mode;
127127

128+
void *map_ptr_real_base;
128129
void *map_ptr_base;
129130
size_t map_ptr_size;
130131
size_t map_ptr_last;

Zend/zend_map_ptr.h

+4-10
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,8 @@
5757
} while (0)
5858
# define ZEND_MAP_PTR_SET_IMM(ptr, val) \
5959
ZEND_MAP_PTR_SET(ptr, val)
60-
# define ZEND_MAP_PTR_REAL_BASE(base) \
61-
(base)
62-
# define ZEND_MAP_PTR_SET_REAL_BASE(base, ptr) do { \
63-
base = (ptr); \
64-
} while (0)
60+
# define ZEND_MAP_PTR_BIASED_BASE(real_base) \
61+
(real_base)
6562
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
6663
# define ZEND_MAP_PTR_NEW_OFFSET() \
6764
((uint32_t)(uintptr_t)zend_map_ptr_new())
@@ -84,11 +81,8 @@
8481
void **__p = ZEND_MAP_PTR_OFFSET2PTR((uintptr_t)ZEND_MAP_PTR(ptr)); \
8582
*__p = (val); \
8683
} while (0)
87-
# define ZEND_MAP_PTR_REAL_BASE(base) \
88-
((void*)(((uintptr_t)(base)) + 1))
89-
# define ZEND_MAP_PTR_SET_REAL_BASE(base, ptr) do { \
90-
base = (void*)(((uintptr_t)(ptr)) - 1); \
91-
} while (0)
84+
# define ZEND_MAP_PTR_BIASED_BASE(real_base) \
85+
((void*)(((uintptr_t)(real_base)) - 1))
9286
#else
9387
# error "Unknown ZEND_MAP_PTR_KIND"
9488
#endif

ext/opcache/ZendAccelerator.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -4347,8 +4347,9 @@ static void preload_load(void)
43474347
size_t old_map_ptr_last = CG(map_ptr_last);
43484348
CG(map_ptr_last) = ZCSG(map_ptr_last);
43494349
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
4350-
ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1));
4351-
memset((void **) ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + old_map_ptr_last, 0,
4350+
CG(map_ptr_real_base) = perealloc(CG(map_ptr_real_base), CG(map_ptr_size) * sizeof(void*), 1);
4351+
CG(map_ptr_base) = ZEND_MAP_PTR_BIASED_BASE(CG(map_ptr_real_base));
4352+
memset((void **) CG(map_ptr_real_base) + old_map_ptr_last, 0,
43524353
(CG(map_ptr_last) - old_map_ptr_last) * sizeof(void *));
43534354
}
43544355
}

0 commit comments

Comments
 (0)