Increase portability by using uintptr_t rather than size_t for pointers

The only integral types guaranteed by the C standard, if they exist, to
support having a pointer cast to them and back are (u)intptr_t. On most
architectures, size_t and uintptr_t are typedefs for the same underlying
type, so this code ends up working. However, on CHERI, and thus Arm's
experimental Morello prototype, C language pointers are implemented with
hardware capabilities, which are unforgeable pointers with bounds and
permissions. This means that, whilst size_t remains a plain 32/64-bit
integer size, (u)intotr_t is represented with a capability. Casting to
size_t and back to a pointer causes the capability metadata to be lost
and the resulting capability to be invalid, meaning it will trap when
dereferenced. Instead, use uintptr_t, and provide fallback definitions
for old versions of MSVC like for the other C99 integer types.
This commit is contained in:
Jessica Clarke 2021-08-06 23:49:16 +01:00
parent 5d30e42c01
commit 9c5654ed44
2 changed files with 9 additions and 2 deletions

View File

@ -33,6 +33,13 @@
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
# if defined(_WIN64)
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
# else
typedef signed __int32 intptr_t;
typedef unsigned __int32 uintptr_t;
# endif
#elif defined(_MSC_VER) // && _MSC_VER >= 1600
# include <stdint.h>
#else

View File

@ -107,7 +107,7 @@ static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
{
char* aligned =
(char*)(
(size_t)(
(uintptr_t)(
zone->chunk_list.ptr + (MSGPACK_ZONE_ALIGN - 1)
) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN
);
@ -120,7 +120,7 @@ static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
{
void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1));
if (ptr) {
return (char*)((size_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN);
return (char*)((uintptr_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN);
}
}
return NULL;