Re: Rust kernel policy

From: H. Peter Anvin
Date: Thu Feb 20 2025 - 09:42:46 EST


On February 20, 2025 6:09:21 AM PST, Martin Uecker <uecker@xxxxxxxxx> wrote:
>Am Donnerstag, dem 20.02.2025 um 16:46 +0300 schrieb Dan Carpenter:
>> On Thu, Feb 20, 2025 at 09:57:29AM +0100, Martin Uecker wrote:
>> > In particulary, I have a relatively concrete plan to have a memory safe
>> > mode for C that can be toggled for some region of code and would make
>> > sure there is no UB or memory safety issues left (I am experimenting with
>> > this in the GCC FE).  So the idea is that one could start to activate this
>> > for certain critical regions of code to make sure there is no signed
>> > integer overflow or OOB access in it.
>>
>> I don't think diferentiating between signed and unsigned integer
>> overflows is useful. In the kernel, most security issues from integer
>> overflows are from unsigned integer overflows. Kees says that we
>> should warn about "Unexpected" behavior instead of "Undefined". In fact,
>> Justin Stitt has done the opposite of what you're doing and only checks
>> for unsigned overflows. He created a sanitizer that warns about integer
>> overflows involving size_t type (which is unsigned), because sizes are
>> so important. (Checking only size_t avoids probably the largest source
>> of harmless integer overflows which is dealing with time).
>
>I agree with you. We were also discussing an attribute that
>can be attached to certain unsigned types to indicate that
>wrapping is an error. 
>
>My more limited aim (because my personal time is very limited)
>is to define a memory safe subset and in such a subset you can
>not have UB. Hence, I am more focussed on signed overflow at
>the moment, but I agree that safety in general must go beyond 
>this.
>
>But this is why I want the kernel community to be more involved,
>to get more resources and more experience into these discussions.
>
>>
>> The sanitizer has a list of exceptions like if (a < a + b) where the
>> integer overflow is idiomatic. But the concern was that there might be
>> other deliberate integer overflows which aren't in the exception list so
>> Justin also created a macro to turn off the santizer.
>>
>> x = wrapping_ok(a + b);
>
>Indeed. This is the main issue with unsigned wraparound. Exactly
>because it was always defined, simply screening for wraparound
>yields many false positives.
>
>(BTW: Rust is also not perfectly immune to such errors:
>https://rustsec.org/advisories/RUSTSEC-2023-0080.html)
>
>
>>
>> What I would like is a similar macro so we could write code like:
>>
>> x = saturate_math(a + b + c + d * d_size);
>>
>> If anything overflowed the result would be ULONG_MAX. In the kernel,
>> we have the size_add() and size_mul() macros which do saturation math
>> instead of wrapping math but we'd have to say:
>>
>> x = size_add(a, size_add(b, size_add(c, size_add(size_mul(d, d_size)))));
>>
>> Which is super ugly. Maybe we could create something like this macro?
>>
>> #define saturate_math(x) ({ \
>> unsigned long res; \
>> __trap_overflow(label_name)); \
>> res = (x); \
>> if (0) { \
>> lable_name: \
>> res = ULONG_MAX; \
>> } \
>> res; \
>> })
>>
>
>We added checked arhithmetic to C23, we could add saturating
>math to C2Y if this is needed. (although I admit I do not fully
>understand the use case of saturating math, a saturated value
>still seems to be an error? Statistics, where it does not matter?)
>
>In general, if people have good ideas what compilers or the language
>standard can do to help, please talk to us. It is possible to
>improve compilers and/or the language itself.
>
>
>Martin
>
>
>
>

This is exactly the sort of things quick is quite easy to do with C++ but requires ad hoc compiler extensions for C.