|
Message-ID: <6d190601-68f1-c086-97ac-2ee1c08f5a34@rasmusvillemoes.dk> Date: Wed, 5 Aug 2020 13:38:58 +0200 From: Rasmus Villemoes <linux@...musvillemoes.dk> To: Kees Cook <keescook@...omium.org> Cc: Jason Gunthorpe <jgg@...pe.ca>, Leon Romanovsky <leon@...nel.org>, "Gustavo A. R. Silva" <gustavoars@...nel.org>, Matthew Wilcox <willy@...radead.org>, linux-kernel@...r.kernel.org, kernel-hardening@...ts.openwall.com, Segher Boessenkool <segher@...nel.crashing.org> Subject: Re: [RFC] saturate check_*_overflow() output? On 04/08/2020 21.23, Kees Cook wrote: > On Tue, Aug 04, 2020 at 08:11:45AM +0200, Rasmus Villemoes wrote: >> What we might do, to deal with the "caller fails to check the result", >> is to add a >> >> static inline bool __must_check must_check_overflow(bool b) { return >> unlikely(b); } >> >> and wrap all the final "did it overflow" results in that one - perhaps >> also for the __builtin_* cases, I don't know if those are automatically >> equipped with that attribute. [I also don't know if gcc propagates >> likely/unlikely out to the caller, but it shouldn't hurt to have it >> there and might improve code gen if it does.] > > (What is the formal name for the ({ ...; return_value; }) C construct?) https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html > Will that work as a macro return value? If so, that's extremely useful. Yes and no. Just wrapping the last expression in the statement expression with my must_check_overflow(), as in @@ -67,17 +72,18 @@ typeof(d) __d = (d); \ (void) (&__a == &__b); \ (void) (&__a == __d); \ - __builtin_sub_overflow(__a, __b, __d); \ + must_check_overflow(__builtin_sub_overflow(__a, __b, __d)); \ }) does not appear to work. For some reason, this can't be (ab)used to overrule the __must_check this simply: - kstrtoint(a, b, c); + ({ kstrtoint(a, b, c); }); still gives a warning for kstrtoint(). But failing to use the result of check_sub_overflow() as patched above does not give a warning. I'm guessing gcc has some internal very early simplification that replaces single-expression statement-exprs with just that expression, and the warn-unused-result triggers later. But as soon as the statement-expr becomes a little non-trivial (e.g. above), my guess is that the whole thing gets assigned to some internal "variable" representing the result, and that assignment then counts as a use of the return value from must_check_overflow() - cc'ing Segher, as he usually knows these details. Anyway, we don't need to apply it to the last expression inside ({}), we can just pass the whole ({}) to must_check_overflow() as in -#define check_sub_overflow(a, b, d) ({ \ +#define check_sub_overflow(a, b, d) must_check_overflow(({ \ typeof(a) __a = (a); \ typeof(b) __b = (b); \ typeof(d) __d = (d); \ (void) (&__a == &__b); \ (void) (&__a == __d); \ __builtin_sub_overflow(__a, __b, __d); \ -}) +})) and that's even more natural for the fallback cases which would be #define check_sub_overflow(a, b, d) \ + must_check_overflow( \ __builtin_choose_expr(is_signed_type(typeof(a)), \ __signed_sub_overflow(a, b, d), \ - __unsigned_sub_overflow(a, b, d)) + __unsigned_sub_overflow(a, b, d))) (in all cases with some whitespace reflowing). Rasmus
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.