Skip to content

dix/privates.c: Avoid undefined behaviour after realloc()

Adding the offset between the realloc result and the old allocation to update pointers into the new allocation is undefined behaviour: the old pointers are no longer valid after realloc() according to the C standard. While this works on almost all architectures and compilers, it causes problems on architectures that track pointer bounds (e.g. CHERI or Arm's Morello): the DevPrivateKey pointers will still have the bounds of the previous allocation and therefore any dereference will result in a run-time trap.

I found this due to a crash (dereferencing an invalid capability) while trying to run XVnc on a CHERI-RISC-V system. With this commit I can successfully connect to the XVnc instance running inside a QEMU with a VNC viewer on my host.

This also changes the check whether the allocation was moved to use uintptr_t instead of a pointer since according to the C standard: "The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime." Casting to an integer type avoids this undefined behaviour.

Edited by Alexander Richardson

Merge request reports