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>