Hi, I noticed that some parts of OpenBSD use awkward techniques to detect undefined behavior in arithmetic operations, for example:
> static size_t > poolBytesToAllocateFor(int blockSize) { > /* Unprotected math would be: > ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); > ** > ** Detect overflow, avoiding _signed_ overflow undefined behavior > ** For a + b * c we check b * c in isolation first, so that addition of a > ** on top has no chance of making us accept a small non-negative number > */ > const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ > > if (blockSize <= 0) > return 0; > > if (blockSize > (int)(INT_MAX / stretch)) > return 0; > > { > const int stretchedBlockSize = blockSize * (int)stretch; > const int bytesToAllocate > = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); > if (bytesToAllocate < 0) > return 0; > > return (size_t)bytesToAllocate; > } > } The snippet was taken from lib/libexpat/lib/xmlparse.c This does not fully protect the code because bytesToAllocate might overflow in the unsigned addition resulting in bytesToAllocate > 0. Note that unsigned overflow is not undefined behavior but leads to unexpected results. C23 solves this problem using <stdckdint.h> [1] which transforms the above function into: > static size_t > poolBytesToAllocateFor(int blockSize) { > size_t add, mul; > if (ckd_mul(&mul, blockSize, sizeof(XML_Char))) > return 0; > if (ckd_add(&add, mul, offsetof(BLOCK, s))) > return 0; > return add; > } Is it worth bringing this functionality in OpenBSD? As a starting point I was thinking that we can make use of __builtin_add_overflow et al. when compiling with Clang. GCC is trickier to solve as the builtins were implemented from version 5. Best Regards, Lucian Popescu [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2681.pdf