Linux 6.2 Looks To Enable "-funsigned-char" To Better Deal With Buggy Code

Written by Michael Larabel in Linux Kernel on 6 December 2022 at 12:00 PM EST. 75 Comments
LINUX KERNEL
Among the early pull requests sent out already ahead of the Linux 6.2 merge window opening next week is a change to enable "-funsigned-char" by default for Linux kernel builds. In preparation for this compiler flag change several fixes have already landed along with a lot of early testing, so any fallout is hoped to be minimal.

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.
Related News
About The Author
Michael Larabel

Michael Larabel is the principal author of Phoronix.com and founded the site in 2004 with a focus on enriching the Linux hardware experience. Michael has written more than 20,000 articles covering the state of Linux hardware support, Linux performance, graphics drivers, and other topics. Michael is also the lead developer of the Phoronix Test Suite, Phoromatic, and OpenBenchmarking.org automated benchmarking software. He can be followed via Twitter, LinkedIn, or contacted via MichaelLarabel.com.

Popular News This Week