Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook
Date: Thu Mar 15 2018 - 18:46:31 EST
On Thu, Mar 15, 2018 at 3:23 PM, Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
> On Thu, Mar 15, 2018 at 3:16 PM, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
>>
>> size_t __error_not_const_arg(void) \
>> __compiletime_error("const_max() used with non-compile-time constant arg");
>> #define const_max(x, y) \
>> __builtin_choose_expr(__builtin_constant_p(x) && \
>> __builtin_constant_p(y), \
>> (typeof(x))(x) > (typeof(y))(y) ? \
>> (x) : (y), \
>> __error_not_const_arg())
>>
>> Is typeof() forcing enums to int? Regardless, I'll put this through
>> larger testing. How does that look?
>
> Ok, that alleviates my worry about one class of insane behavior, but
> it does raise a few other questions:
>
> - what drugs is gcc on where (typeof(x)(x)) makes a difference? Funky.
Yeah, that's why I didn't even try that originally. But in looking
back at max() again, it seemed to be the only thing missing that would
handle the enum evaluation, which turned out to be true.
> - this does have the usual "what happen if you do
>
> const_max(-1,sizeof(x))
>
> where the comparison will now be done in 'size_t', and -1 ends up
> being a very very big unsigned integer.
>
> Is there no way to get that type checking inserted? Maybe now is a
> good point for that __builtin_types_compatible(), and add it to the
> constness checking (and change the name of that error case function)?
So, AIUI, I can either get strict type checking, in which case, this
is rejected (which I assume there is still a desire to have):
int foo[const_max(6, sizeof(whatever))];
due to __builtin_types_compatible_p() rejecting it, or I can construct
a "positive arguments only" test, in which the above is accepted, but
this is rejected:
int foo[const_max(-1, sizeof(whatever))];
By using this eye-bleed:
size_t __error_not_const_arg(void) \
__compiletime_error("const_max() used with non-compile-time constant arg");
size_t __error_not_positive_arg(void) \
__compiletime_error("const_max() used with negative arg");
#define const_max(x, y) \
__builtin_choose_expr(__builtin_constant_p(x) && \
__builtin_constant_p(y), \
__builtin_choose_expr((x) >= 0 && (y) >= 0, \
(typeof(x))(x) > (typeof(y))(y) ? \
(x) : (y), \
__error_not_positive_arg()), \
__error_not_const_arg())
-Kees
--
Kees Cook
Pixel Security