| #include <cheri.hh> | 
 |  | 
 | using namespace CHERI; | 
 |  | 
 | /** | 
 |  * C API for `check_pointer`. | 
 |  * | 
 |  * See `cheri.hh` for more information. | 
 |  */ | 
 | bool check_pointer(const void *ptr, | 
 |                    size_t      space, | 
 |                    uint32_t    rawPermissions, | 
 |                    bool        checkStackNeeded) | 
 | { | 
 | 	auto permissions = PermissionSet::from_raw(rawPermissions); | 
 | 	Capability<const void> cap{ptr}; | 
 | 	bool                   isValid = cap.is_valid() && !cap.is_sealed(); | 
 | 	// Skip the stack check if we're requiring a global capability.  By | 
 | 	// construction, such a thing cannot be derived from the stack | 
 | 	// pointer. | 
 | 	if (checkStackNeeded) | 
 | 	{ | 
 | 		Capability<void> stack{__builtin_cheri_stack_get()}; | 
 | 		// Check that the capability does not overlap the | 
 | 		// stack. The base of the capability is <= its top, so | 
 | 		// the capability is in bounds as long as either: | 
 | 		// - its top is below the current stack or; | 
 | 		// - its base is above the top of the current stack. | 
 | 		isValid &= (cap.top() <= stack.base()) || (cap.base() >= stack.top()); | 
 | 	} | 
 | 	isValid &= cap.bounds() >= space; | 
 | 	// Check that we have, at least, the required permissions | 
 | 	isValid &= permissions.can_derive_from(cap.permissions()); | 
 | 	return isValid; | 
 | } | 
 |  | 
 | bool __cheri_libcall check_timeout_pointer(const struct Timeout *timeout) | 
 | { | 
 | 	return !heap_address_is_valid(timeout) && | 
 | 	       check_pointer( | 
 | 	         timeout, | 
 | 	         sizeof(struct Timeout), | 
 | 	         PermissionSet{Permission::Load, Permission::Store}.as_raw(), | 
 | 	         false); | 
 | } |