On Sun, May 12, 2024 at 09:09:08AM -0700, Linus Torvalds wrote: > unsigned char *p; > u32 val; > > p[0] = val; > p[1] = val >> 8; > p[2] = val >> 16; > p[3] = val >> 24; > > kind of code is both traditional and correct, but obviously drops bits > very much intentionally on each of those assignments.
The good news here is that the integer implicit truncation sanitizers are already split between "signed" and "unsigned". So the 2 cases of exploitable flaws mentioned earlier: u8 num_elems; ... num_elems++; /* int promotion stored back to u8 */ and int size; u16 read_size; ... read_size = size; /* large int stored to u16 */ are both confusions across signed/unsigned types, which the signed sanitizer would catch. The signed sanitizer would entirely ignore the quoted example at the top: everything is unsigned and no int promotion is happening. So, I think we can start with just the "signed integer implicit truncation" sanitizer. The compiler will still need to deal with the issues I outlined in [1], where I think we need some consideration specifically on how to handle things like this (that have a smaller-than-int size and trip the sanitizer due to int promotion): u8 checksum(const u8 *buf) { u8 sum = 0; for (int i = 0; i < 4; i++) sum += buf[i]; /* int promotion */ return sum; } We want "sum" to wrap. We could avoid the "implicit" truncation by explicitly truncating with something eye-bleedingly horrible like: sum = (u8)(sum + buf[i]); Adding a wrapper for the calculation could work but repeats "sum", and needs to be explicitly typed, making it just as unfriendly: sum = truncate(u8, sum + buf[i]); Part of the work I'd done in preparation for all this was making the verbosely named wrapping_assign_add() helper which handles all the types by examining the arguments and avoids repeating the destination argument. So this would become: wrapping_assign_add(sum, buf[i]); Still not as clean as "+=", but at least more readable than the alternatives and leaves no question about wrapping intent. -Kees [1] https://lore.kernel.org/lkml/202405081949.0565810E46@keescook/ -- Kees Cook