Skip to content

Commit 500451b

Browse files
MauriceDHanischbsdjhb
authored andcommitted
jemalloc: use get_underlying_allocation in je_malloc_underlying_allocation
Add get_underlying_allocation() helper function that properly resolves sub-capabilities (interior pointers) to their underlying allocation. This correctly handles the case where a pointer points within a slab allocation by calculating the region base from the extent. Use this new function in je_malloc_underlying_allocation() instead of the previous unbound_ptr approach which had issues with interior pointers.
1 parent 453e79a commit 500451b

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_c.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,63 @@
2121
#include "jemalloc/internal/sz.h"
2222
#include "jemalloc/internal/witness.h"
2323

24+
JEMALLOC_ALWAYS_INLINE void *
25+
get_underlying_allocation(tsdn_t *tsdn, void *ptr) {
26+
void *ubptr;
27+
28+
#ifndef __CHERI_PURE_CAPABILITY__
29+
ubptr = ptr;
30+
#else
31+
rtree_ctx_t *rtree_ctx;
32+
rtree_ctx_t rtree_ctx_fallback;
33+
extent_t *extent;
34+
szind_t szind;
35+
36+
/*
37+
* These checks catch attacks from an adversary that can manipulate the
38+
* offset and the bounds of a ptr passed to free() or realloc().
39+
* Reject zero-length capabilities: region arithmetic can misclassify an
40+
* end-of-region pointer as the start of the next region.
41+
*/
42+
if (unlikely(!cheri_gettag(ptr))) {
43+
return NULL;
44+
}
45+
if (unlikely(cheri_getoffset(ptr) > cheri_getlen(ptr))) {
46+
return NULL;
47+
}
48+
if (unlikely(cheri_getlen(ptr) == 0)) {
49+
return NULL;
50+
}
51+
if (unlikely(cheri_getsealed(ptr))) {
52+
return NULL;
53+
}
54+
55+
rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback);
56+
if (rtree_extent_szind_read(tsdn, &extents_rtree, rtree_ctx,
57+
(uintptr_t)ptr, false, &extent, &szind)) {
58+
return NULL;
59+
}
60+
61+
assert(extent_state_get(extent) == extent_state_active);
62+
/* Only slab members should be looked up via interior pointers. */
63+
assert(extent_addr_get(extent) == ptr || extent_slab_get(extent));
64+
assert(szind != SC_NSIZES);
65+
66+
size_t underlying_size = sz_index2size(szind);
67+
void *extent_base = extent->e_addr;
68+
69+
size_t offset = (uintptr_t)ptr - (uintptr_t)extent_base;
70+
size_t region_index = offset / underlying_size;
71+
void *region_base = (void *)((uintptr_t)extent_base +
72+
region_index * underlying_size);
73+
74+
ubptr = cheri_setbounds(
75+
cheri_setaddress(extent_base, (ptraddr_t)region_base),
76+
underlying_size);
77+
#endif
78+
return ubptr;
79+
}
80+
2481
JEMALLOC_ALWAYS_INLINE void *
2582
unbound_ptr(tsdn_t *tsdn, void *ptr) {
2683
void *ubptr;

contrib/jemalloc/src/jemalloc.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,22 +3799,18 @@ je_malloc_underlying_allocation(void *ptr) {
37993799
if (unlikely(ptr == NULL)) {
38003800
ret = NULL;
38013801
} else {
3802-
size_t underlying_size = ivsalloc(tsdn, ptr);
3803-
if (underlying_size == 0) {
3802+
ret = get_underlying_allocation(tsdn, ptr);
3803+
ret = cheri_andperm(ret,
3804+
CHERI_PERMS_USERSPACE_DATA | CHERI_PERM_SW_VMEM);
3805+
}
3806+
3807+
/*
3808+
* Check that ptr corresponds to a ptr returned by malloc.
3809+
*/
3810+
if (ret != NULL) {
3811+
void *ret_check = cheri_andperm(ret, ~CHERI_PERM_SW_VMEM);
3812+
if (unlikely(!cheri_equal_exact(ptr, ret_check))) {
38043813
ret = NULL;
3805-
} else {
3806-
/*
3807-
* XXX unbound_ptr will actually work if this isn't
3808-
* a pointer to an original allocation but is
3809-
* contained within an extent - we can
3810-
* probably fix this in rtree functions.
3811-
*/
3812-
ret = unbound_ptr(tsdn, ptr);
3813-
/* Bounds as with BOUND_PTR, but preserve SW_VMEM */
3814-
if (ret != NULL)
3815-
ret = cheri_andperm(
3816-
cheri_setbounds(ret, underlying_size),
3817-
CHERI_PERMS_USERSPACE_DATA | CHERI_PERM_SW_VMEM);
38183814
}
38193815
}
38203816

0 commit comments

Comments
 (0)