Linux 6.2 Looks To Enable "-funsigned-char" To Better Deal With Buggy Code
The "-funsigned-char" compiler flag makes all "char" character types as unsigned if not otherwise specified. For kernel code written as using the plain "char" type, this change moving forward will universally treat the default char type as unsigned -- rather than the default CPU architecture / compiler preference that may be signed or unsigned.
Security researcher and WireGuard lead developer Jason Donenfeld led the work on the -funsigned-char conversion of the Linux kernel. He sent in an early pull request that enables the unsigned char behavior by default as well as various kernel fixes for where the kernel code had made varying assumptions over the signedness of char types. Additional char signedness fixes have already been merged for the Linux 6.1 cycle.
As what go Donenfeld working on this messy char signedness issue within the kernel, he commented with this patch:
Recently, some compile-time checking I added to the clamp_t family of functions triggered a build error when a poorly written driver was compiled on ARM, because the driver assumed that the naked `char` type is signed, but ARM treats it as unsigned, and the C standard says it's architecture-dependent.
I doubt this particular driver is the only instance in which unsuspecting authors make assumptions about `char` with no `signed` or `unsigned` specifier. We were lucky enough this time that that driver used `clamp_t(char, negative_value, positive_value)`, so the new checking code found it, and I've sent a patch to fix it, but there are likely other places lurking that won't be so easily unearthed.
So let's just eliminate this particular variety of heisensign bugs entirely. Set `-funsigned-char` globally, so that gcc makes the type unsigned on all architectures.
This will break things in some places and fix things in others, so this will likely cause a bit of churn while reconciling the type misuse.
As for the prospects of trouble from this fundamental change, Donenfeld commented in the pull request:
The various fixes were found with a combination of diffing objdump output, a large variety of Coccinelle scripts, and plain old grep. In the end, things didn't seem as bad as I feared they would. But of course, it's also possible I missed things. However, this has been in linux-next for basically an entire cycle now, so I'm not overly worried. I've also been daily driving this on my laptop for all of 6.1. Still, this series, and the ones sent for 6.1 don't total in quantity to what I thought it'd be, so I will be on the lookout for breakage.
We could receive a few reports that are quickly fixable. Hopefully we won't receive a barrage of reports that would result in a revert. And just maybe we won't receive any reports at all and nobody will even notice. Knock on wood.