Skip to content

Unaligned capability copies

Alexander Richardson edited this page Aug 27, 2019 · 3 revisions

Copying a capability to an unaligned destination will result in tag bits being stripped since they are only retained when using copies with csc/clc instructions.

Diagnosed function calls: memcpy(), memmove(), __builtin_memcpy() and __builtin_memmove()

There are two issues that need to be considered here:

Correctness and tag stripping

For example the following code will sometimes result in buffer not containing the tag bit from value:

void test(uintcap_t value) {
    char buffer[sizeof(uintcap_t)];
    memcpy(buffer, &value, sizeof(value));
    do_something(buffer);
}

If buffer happens to be aligned to alignof(void*__capability) (i.e. 16 bytes or 32 for CHERI256) at runtime then a call to memcpy() will result in the tag bits being copied because memcpy() will use csc/clc. However, if it is only aligned to four or eight bytes, then memcpy() will end up using clw or cld instructions and produce a byte-by-byte indetical copy of the capability but without the tag bit set.

Efficiency

If you use memcpy() with a source type containing capability to copy to a buffer that the compiler cannot statically prove to be at least capability aligned, the compiler will not be able to expand the memcpy() to a sequence of loads and stores (even for a single capability-size copy). This extra function call can cause performance degradation, however, emitting the clc/csc unconditionally could result in traps at runtime. As memcpy() must work with unaligned data, this is not an option and we instead warn for potentially tag-stripping copies.

Cases that cannot be diagnosed

void* my_copy(void* dst, void* src) {
    // The following could be expanded inline by the compiler and strip tags.
    // This is possible since the size is a constant and small enough to be
    // expanded in a few instructions. 
    return memcpy(dst, src, sizeof(uincap_t));
}

Note: we could diagnose copies with a void* source and assume these might contain capabilities but that would almost certainly be an extremely noisy warning.