Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Feb 2016 14:21:39 +0100
From:      Ed Schouten <ed@nuxi.nl>
To:        C Turt <cturt@hardenedbsd.org>
Cc:        arch@freebsd.org
Subject:   Re: OpenBSD mallocarray
Message-ID:  <CABh_MKmtC0OPPkNU0ho2UZsnVrbRO1w6vHjidYhKqgu123PVCg@mail.gmail.com>
In-Reply-To: <CAB815ZafpqJoqr1oH8mDJM=0RxLptQJpoJLexw6P6zOi7oSXTQ@mail.gmail.com>
References:  <CAB815ZafpqJoqr1oH8mDJM=0RxLptQJpoJLexw6P6zOi7oSXTQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi there,

2016-02-01 20:57 GMT+01:00 C Turt <cturt@hardenedbsd.org>:
>     if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
>         nmemb > 0 && SIZE_MAX / nmemb < size) {

In my opinion functions like these are good additions, as long as we
make sure that we stop importing garbage expressions like the one
above. It's already bad enough that we copy-pasted this gobbledygook
into fread(), fwrite(), calloc(), reallocarray(), etc.

Both the latest versions of Clang and GCC support the following builtins:

bool __builtin_add_overflow(type1 a, type2 b, type3 *res);
bool __builtin_sub_overflow(type1 a, type2 b, type3 *res);
bool __builtin_mul_overflow(type1 a, type2 b, type3 *res);

These functions perform addition, subtraction and multiplication,
returning whether overflow has occurred in the process. This is a lot
more efficient (and readable) than the expression above, as it simply
uses the CPU's mul instruction, followed by a jump-on-overflow.

GCC 4.2.1 doesn't support these builtins, but they can easily be
emulated by using static inline functions that use the code above. If
we want them to be type generic, we can use <sys/cdefs.h>'s
__generic(), which either expands to C11's _Generic() or falls back to
GCC's __builtin_types_compatible_p()/__builtin_choose_expr().

I'd say it would make a lot of sense to add a new header file, e.g.
<sys/overflow.h>, that adds compiler-independent wrappers for these
builtins:

#if recent version of GCC/Clang
#define add_overflow(a, b, res) __builtin_add_overflow(a, b, res)
#else
#define add_overflow(a, b, res) (__generic(*(res), unsigned int, ...,
...)(a, b, res))
#endif

-- 
Ed Schouten <ed@nuxi.nl>
Nuxi, 's-Hertogenbosch, the Netherlands
KvK-nr.: 62051717



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CABh_MKmtC0OPPkNU0ho2UZsnVrbRO1w6vHjidYhKqgu123PVCg>