(fwiw, Android has someone working on adding this header to upstream
LLVM right now, so hopefully it should come "for free" in llvm 18.
what, if anything, to _do_ with it is another question though :-) )

On Mon, Aug 7, 2023 at 9:09 AM Lucian Popescu
<lucian.popescu...@gmail.com> wrote:
>
> 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

Reply via email to