/* * Check for high-precision bounds for a variety of small object sizes, * allocated from the stack. These should be precise regardless of capability * compression, as the allocator promises to align things suitably. Test both * static and dynamic allocation. */ static void test_bounds_precise(__capability void *c, size_t expected_len) { size_t len, offset; /* Confirm precise lower bound: offset of zero. */ offset = cheri_getoffset(c); if (offset != 0) cheritest_failure_errx("offset (%jd) not zero", offset); /* Confirm precise upper bound: length of expected size for type. */ len = cheri_getlen(c); if (len != expected_len) cheritest_failure_errx("length (%jd) not expected %jd", len, expected_len); cheritest_success(); }
register_t cheritest_libcheri_userfn_getstack(void) { struct cheri_stack cs; struct cheri_stack_frame *csfp; u_int stack_depth; int retval; retval = sysarch(CHERI_GET_STACK, &cs); if (retval != 0) cheritest_failure_err("sysarch(CHERI_GET_STACK) failed"); /* Does stack layout look sensible enough to continue? */ if ((cs.cs_tsize % CHERI_FRAME_SIZE) != 0) cheritest_failure_errx( "stack size (%ld) not a multiple of frame size", cs.cs_tsize); stack_depth = cs.cs_tsize / CHERI_FRAME_SIZE; if ((cs.cs_tsp % CHERI_FRAME_SIZE) != 0) cheritest_failure_errx( "stack pointer (%ld) not a multiple of frame size", cs.cs_tsp); /* Validate that two stack frames are found. */ if (cs.cs_tsp != cs.cs_tsize - (register_t)(2 * CHERI_FRAME_SIZE)) cheritest_failure_errx("stack contains %d frames; expected " "2", (cs.cs_tsize - (2 * CHERI_FRAME_SIZE)) / CHERI_FRAME_SIZE); /* Validate that the first is a saved ambient context. */ csfp = &cs.cs_frames[stack_depth - 1]; if (cheri_getbase(csfp->csf_pcc) != cheri_getbase(cheri_getpcc()) || cheri_getlen(csfp->csf_pcc) != cheri_getlen(cheri_getpcc())) cheritest_failure_errx("frame 0: not global code cap"); /* Validate that the second is cheritest_objectp. */ csfp = &cs.cs_frames[stack_depth - 2]; if ((cheri_getbase(csfp->csf_pcc) != cheri_getbase( sandbox_object_getobject(cheritest_objectp).co_codecap)) || cheri_getlen(csfp->csf_pcc) != cheri_getlen( sandbox_object_getobject(cheritest_objectp).co_codecap)) cheritest_failure_errx("frame 1: not sandbox code cap"); return (0); }
/* * Check that the bytes of a buffer in the range (buf + offset) to * (buf + offset + len - 1) are those expected from fillbuf(). */ static void checkbuf(const char *buf, size_t offset, size_t len, const char *where) { size_t i; for (i = offset; i < offset + len; i++) { if (buf[i] != (char)(i & 0xFF)) cheritest_failure_errx("%s: buf[%zu] != 0x%02x (0x%02x)", where, i, (char)(i & 0xFF), buf[i]); } }