Torvalds Voices Thoughts On Linux Mitigating Unexpected Arithmetic Overflows/Underflows
For those interested in some insightful Linux kernel mailing list reading this weekend, there's been a vibrant discussion on the ability for the Linux kernel to mitigate unexpected arithmetic overflows/underflows/wraparounds.
Kees Cook with Google has been working on figuring out how to better deal with unexpected arithmetic overflow bugs within the Linux kernel's C source code. He's hoping to see a systematic way for the Linux kernel to be able to deal with such arithmetic overflow/underflow/wrap-around problems. Among the initial thinking is to better engage compiler-based sanitizers or a recent C language proposal for operator overloading without name mangling. In the latter proposal as a potential solution, C operator overloading could allow for arbitrary handling of overflows within the helpers.
Kees initial thinking has been on pursuing sanitizer-based mitigations and concluded his mailing list thread with:
Linus Torvalds was quick to share his thoughts on the proposal:
Some clear-cut communication from Linus Torvalds. He later added:
As another follow-up he suggested taking more baby steps toward a potential solution. The discussions remain ongoing so we'll see how the discussion evolves and ultimately what code ends up being proposed for trying to better deal with the Linux kernel's C code for mitigating potential unexpected arithmetic overflows/wrap-arounds.
Kees Cook with Google has been working on figuring out how to better deal with unexpected arithmetic overflow bugs within the Linux kernel's C source code. He's hoping to see a systematic way for the Linux kernel to be able to deal with such arithmetic overflow/underflow/wrap-around problems. Among the initial thinking is to better engage compiler-based sanitizers or a recent C language proposal for operator overloading without name mangling. In the latter proposal as a potential solution, C operator overloading could allow for arbitrary handling of overflows within the helpers.
Kees initial thinking has been on pursuing sanitizer-based mitigations and concluded his mailing list thread with:
"I'm seeking some general consensus on taking approach #1 above. Any solution that actually gains us meaningful coverage is going to require pretty extensive changes to Linux's types so that's a universal pain point. But I've been beating the "make Linux safer" drum for a long time now, and I hope I can convince folks that we need to actually make a change here. The status quo isn't good enough, and we can do better. I just need to find a common solution we can agree on and realistically apply over the coming years.
I'll go get my asbestos suit now... What are your thoughts, suggestions, alternatives?"
Linus Torvalds was quick to share his thoughts on the proposal:
"I'm still entirely unconvinced.
The thing is, wrap-around is not only well-defined, it's *common*, and *EXPECTED*.
Example:
static inline u32 __hash_32_generic(u32 val)
{
return val * GOLDEN_RATIO_32;
}
and dammit, I absolutely DO NOT THINK we should annotate this as some kind of "special multiply".
I have no idea how many of these exist. But I am 100% convinced that making humans annotate this and making the source code worse is absolutely the wrong approach.
Basically, unsigned arithmetic is well-defined as wrapping around, and it is so for a good reason.
So I'm going to have a HARD REQUIREMENT that any compiler complaints need to be really really sane. They need to detect when people do things like this on purpose, and they need to SHUT THE ^&% UP about the fact that wrap-around happens.
Any tool that is so stupid as to complain about wrap-around in the above is a BROKEN TOOL THAT NEEDS TO BE IGNORED.
Really. This is non-negotiable.
This is similar to the whole
unsigned int a, b;
if (a+b < a) ..
kind of pattern: a tool that complains about wrap-around in the above is absolutely broken sh*t and needs to be ignored.
So I think you need to limit your wrap-around complaints, and really think about how to limit them. If you go "wrap-around is wrong" as some kind of general; rule, I'm going to ignore you, and I'm going to tell people to ignore you, and refuse any idiotic patches that are the result of such idiotic rules.
Put another way the absolute first and fundamental thing you should look at is to make sure tools don't complain about sane behavior.
Until you have done that, and taken this seriously, this discussion is not going to ever result in anything productive.
Linus"
Some clear-cut communication from Linus Torvalds. He later added:
"Any kind of mindless "this can wrap around" is inexcusable.
It needs to be smarter than that. And yes, that means exactly taking into account how the result of the possible wrap-around is actually used.
If it's used as a size or as an array index, it might be a problem. But if it's used for masking and then a *masked* version is used for an index, it clearly is NOT a problem.
IOW, exactly the same as "a+b < a". Yes, "a+b" might wrap around, but if the use is to then compare it with one of the addends, then clearly such a wrap-around is fine.
A tool that doesn't look at how the result is used, and just blindly says "wrap-around error" is a tool that I think is actively detrimental.
And no, the answer is ABSOLUTELY NOT to add cognitive load on kernel developers by adding yet more random helper types and/or functions.
We already expect a lot of kernel developers. We should not add on to that burden because of your pet project.
Put another way: I'm putting the onus on YOU to make sure your pet project is the "Yogi Bear" of pet projects - smarter than the average bear.
As long as you are approaching this from a "this puts the onus on others", *YOU* are the problem.
Be the solution, not the problem.
Linus"
As another follow-up he suggested taking more baby steps toward a potential solution. The discussions remain ongoing so we'll see how the discussion evolves and ultimately what code ends up being proposed for trying to better deal with the Linux kernel's C code for mitigating potential unexpected arithmetic overflows/wrap-arounds.
99 Comments