Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around

From: Kent Overstreet
Date: Mon Jan 22 2024 - 21:41:16 EST


On Mon, Jan 22, 2024 at 04:26:35PM -0800, Kees Cook wrote:
> Hi,
>
> In our continuing effort to eliminate root causes of flaws in the kernel,
> this series is the start to providing a way to have sensible coverage
> for catching unexpected arithmetic wrap-around.
>
> A quick word on language: while discussing[1] the finer details of
> the C standard's view on arithmetic, I was disabused of using the term
> "overflow" when what I really mean is "wrap-around". When describing
> security vulnerabilities, "overflow" is the common term and often used
> interchangeably with "wrap-around". Strictly speaking, though, "overflow"
> applies only to signed[2] and pointer[3] types, and "wrap-around" is for
> unsigned[4]. An arithmetic "overflow" is considered undefined behavior,
> which has caused our builds pain in the past, since "impossible"
> conditions might get elided by the compiler. As a result, we build
> with -fno-strict-overflow which coverts all "overflow" conditions into
> "wrap-around" (i.e. 2s complement), regardless of type.
>
> All this is to say I am discussing arithmetic wrap-around, which is
> the condition where the value exceeds a type's maximum value (or goes
> below its minimum value) and wraps around. I'm not interested in the
> narrow definition of "undefined behavior" -- we need to stamp out the
> _unexpected_ behavior, where the kernel operates on a pathological value
> that wrapped around without the code author's intent.
>
> As always, this is about being able disambiguate the intent of arithmetic
> in the kernel. We intentionally use wrapping arithmetic in all kinds of
> places, but we need to be able to annotate it as such going forward so
> the compiler can distinguish when it needs to perform instrumentation
> (when such instrumentation is enabled).
>
> Getting back to my earlier mention of -fno-strict-overflow, the bulk of
> the series is refactoring for a common code pattern in the kernel where
> to test for potentially overflowing addition, the addition is performed,
> and wrap-around is tested for. This is what originally[5] caused us to
> enable -fno-strict-overflow:
>
> var + offset < var
>
> For these cases we can use either check_add_overflow() or
> add_would_overflow(). These helpers will not trip the wrap-around
> instrumentation, and do not depend on the whims of the compiler options.
> (Note that I have no intention of removing -fno-strict-overflow any
> time soon, if ever. As with all these kinds of changes, we need to
> evolve our support for it, and we can't introduce undefined behavior
> into the kernel.)
>
> This series is mainly 3 parts:

This all seems fine, but... Rust already has this at the type system
level....

I know you're not one of the people bringing bickering into the Rust
threads, so I'm wondering if perhaps your secret plan is to annoy the
die hard "I want everything to be fast with razor blades everywhere" C
programmers enough to finally get onboard the "let's just switch to a
language with less razor wire" train.