Small alloca() have unnecessarily padded bounds
Our CheriABI integration test cases for small dynamic stack allocations using alloc()
show a minimum bounds of 16 bytes, rather than being byte granularity:
TEST: test_bounds_stack_dynamic_uint8: Check bounds on 8-bit dynamic stack allocation
FAIL: test_bounds_stack_dynamic_uint8: length (16) not expected 1: 0x0000fffffff3cf90 [rwRW,0x0000fffffff3cf90-0x0000fffffff3cfa0]
TEST: test_bounds_stack_dynamic_uint16: Check bounds on 16-bit dynamic stack allocation
FAIL: test_bounds_stack_dynamic_uint16: length (16) not expected 2: 0x0000fffffff3cf90 [rwRW,0x0000fffffff3cf90-0x0000fffffff3cfa0]
TEST: test_bounds_stack_dynamic_uint32: Check bounds 32-bit dynamic stack allocation
FAIL: test_bounds_stack_dynamic_uint32: length (16) not expected 4: 0x0000fffffff3cf90 [rwRW,0x0000fffffff3cf90-0x0000fffffff3cfa0]
TEST: test_bounds_stack_dynamic_uint64: Check bounds on 64-bit dynamic stack allocation
FAIL: test_bounds_stack_dynamic_uint64: length (16) not expected 8: 0x0000fffffff3cf90 [rwRW,0x0000fffffff3cf90-0x0000fffffff3cfa0]
The test cases are as follows:
static void
test_bounds_stack_alloca(size_t len)
{
void * __capability c = (__cheri_tocap void * __capability)alloca(len);
test_bounds_precise(c, len);
}
void
test_bounds_stack_dynamic_uint8(const struct cheri_test *ctp __unused)
{
test_bounds_stack_alloca(sizeof(uint8_t));
}
void
test_bounds_stack_dynamic_uint16(const struct cheri_test *ctp __unused)
{
test_bounds_stack_alloca(sizeof(uint16_t));
}
void
test_bounds_stack_dynamic_uint32(const struct cheri_test *ctp __unused)
{
test_bounds_stack_alloca(sizeof(uint32_t));
}
void
test_bounds_stack_dynamic_uint64(const struct cheri_test *ctp __unused)
{
test_bounds_stack_alloca(sizeof(uint64_t));
}
Full test suite here: https://github.com/CTSRD-CHERI/cheribsd/tree/master/bin/cheritest
Tagging @jrtc27 @brett.gutstein @arichardson as FYIs.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information