mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-04-14 22:51:50 +03:00
Fix off-by-one in arenas_bin_i_index and arenas_lextent_i_index bounds checks
The index validation used > instead of >=, allowing access at index SC_NBINS (for bins) and SC_NSIZES-SC_NBINS (for lextents), which are one past the valid range. This caused out-of-bounds reads in bin_infos[] and sz_index2size_unsafe(). Add unit tests that verify the boundary indices return ENOENT.
This commit is contained in:
parent
a87c518bab
commit
27773c44e5
2 changed files with 49 additions and 2 deletions
|
|
@ -3255,7 +3255,7 @@ CTL_RO_NL_GEN(arenas_bin_i_slab_size, bin_infos[mib[2]].slab_size, size_t)
|
|||
CTL_RO_NL_GEN(arenas_bin_i_nshards, bin_infos[mib[2]].n_shards, uint32_t)
|
||||
static const ctl_named_node_t *
|
||||
arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
|
||||
if (i > SC_NBINS) {
|
||||
if (i >= SC_NBINS) {
|
||||
return NULL;
|
||||
}
|
||||
return super_arenas_bin_i_node;
|
||||
|
|
@ -3267,7 +3267,7 @@ CTL_RO_NL_GEN(arenas_lextent_i_size,
|
|||
static const ctl_named_node_t *
|
||||
arenas_lextent_i_index(
|
||||
tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
|
||||
if (i > SC_NSIZES - SC_NBINS) {
|
||||
if (i >= SC_NSIZES - SC_NBINS) {
|
||||
return NULL;
|
||||
}
|
||||
return super_arenas_lextent_i_node;
|
||||
|
|
|
|||
|
|
@ -956,6 +956,52 @@ TEST_BEGIN(test_arenas_bin_constants) {
|
|||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_bin_oob) {
|
||||
size_t sz;
|
||||
size_t result;
|
||||
char buf[128];
|
||||
|
||||
/*
|
||||
* Querying the bin at index SC_NBINS should fail because valid
|
||||
* indices are [0, SC_NBINS).
|
||||
*/
|
||||
sz = sizeof(result);
|
||||
malloc_snprintf(
|
||||
buf, sizeof(buf), "arenas.bin.%u.size", (unsigned)SC_NBINS);
|
||||
expect_d_eq(mallctl(buf, (void *)&result, &sz, NULL, 0), ENOENT,
|
||||
"mallctl() should fail for out-of-bounds bin index SC_NBINS");
|
||||
|
||||
/* One below the boundary should succeed. */
|
||||
malloc_snprintf(
|
||||
buf, sizeof(buf), "arenas.bin.%u.size", (unsigned)(SC_NBINS - 1));
|
||||
expect_d_eq(mallctl(buf, (void *)&result, &sz, NULL, 0), 0,
|
||||
"mallctl() should succeed for valid bin index SC_NBINS-1");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_lextent_oob) {
|
||||
size_t sz;
|
||||
size_t result;
|
||||
char buf[128];
|
||||
unsigned nlextents = SC_NSIZES - SC_NBINS;
|
||||
|
||||
/*
|
||||
* Querying the lextent at index nlextents should fail because valid
|
||||
* indices are [0, nlextents).
|
||||
*/
|
||||
sz = sizeof(result);
|
||||
malloc_snprintf(buf, sizeof(buf), "arenas.lextent.%u.size", nlextents);
|
||||
expect_d_eq(mallctl(buf, (void *)&result, &sz, NULL, 0), ENOENT,
|
||||
"mallctl() should fail for out-of-bounds lextent index");
|
||||
|
||||
/* Querying the last element (nlextents - 1) should succeed. */
|
||||
malloc_snprintf(
|
||||
buf, sizeof(buf), "arenas.lextent.%u.size", nlextents - 1);
|
||||
expect_d_eq(mallctl(buf, (void *)&result, &sz, NULL, 0), 0,
|
||||
"mallctl() should succeed for valid lextent index");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_lextent_constants) {
|
||||
#define TEST_ARENAS_LEXTENT_CONSTANT(t, name, expected) \
|
||||
do { \
|
||||
|
|
@ -1450,6 +1496,7 @@ main(void) {
|
|||
test_arena_i_dss, test_arena_i_name, test_arena_i_retain_grow_limit,
|
||||
test_arenas_dirty_decay_ms, test_arenas_muzzy_decay_ms,
|
||||
test_arenas_constants, test_arenas_bin_constants,
|
||||
test_arenas_bin_oob, test_arenas_lextent_oob,
|
||||
test_arenas_lextent_constants, test_arenas_create,
|
||||
test_arenas_lookup, test_prof_active, test_stats_arenas,
|
||||
test_stats_arenas_hpa_shard_counters,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue