GCC undefined behaviors are getting wild
source link: http://blog.pkh.me/p/37-gcc-undefined-behaviors-are-getting-wild.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
GCC undefined behaviors are getting wild
Happy with my recent breakthrough in understanding C integer divisions
after weeks of struggle, I was minding my own business having fun writing
integer arithmetic code. Life was good, when suddenly… zsh: segmentation fault (core dumped)
.
That code wasn't messing with memory much so it was more likely to be a side
effect of an overflow or something. Using -fsanitize=undefined
quickly
identified the issue, which confirmed the presence of an integer overflow. The
fix was easy but something felt off. I was under the impression my code was
robust enough against that kind of honest mistake. Turns out, the protecting
condition I had in place should indeed have been enough, so I tried to extract
a minimal reproducible case:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
uint8_t tab[0x1ff + 1];
uint8_t f(int32_t x)
{
if (x < 0)
return 0;
int32_t i = x * 0x1ff / 0xffff;
if (i >= 0 && i < sizeof(tab)) {
printf("tab[%d] looks safe because %d is between [0;%d[\n", i, i, (int)sizeof(tab));
return tab[i];
}
return 0;
}
int main(int ac, char **av)
{
return f(atoi(av[1]));
}
The overflow can happen on i
assignment. Since an integer overflow is
undefined, GCC makes the assumption that it cannot happen, ever. In practice in
this case it does, but the i >= 0 && i < sizeof(tab)
condition should be
enough to take care of it, whatever crazy value it becomes, right? Well, I have
bad news:
% cc -Wall -O2 overflow.c -o overflow && ./overflow 50000000
tab[62183] looks safe because 62183 is between [0;512[
zsh: segmentation fault (core dumped) ./overflow 50000000
Note: this is GCC 12.2.0
on x86-64.
We have i=62183
as the result of the overflow, and nevertheless the execution
violates the gate condition, spout a non-sense lie, go straight into
dereferencing tab
, and die miserably.
Let's study what GCC is doing here. Firing up Ghidra we observe the following decompiled code:
uint8_t f(int x)
{
int tmp;
if (-1 < x) {
tmp = x * 0x1ff;
if (tmp < 0x1fffe00) {
printf("tab[%d] looks safe because %d is between [0;%d[\n",(ulong)(uint)tmp / 0xffff, (ulong)(uint)tmp / 0xffff,0x200);
return tab[(int)((uint)tmp / 0xffff)];
}
}
return '\0';
}
When I said GCC makes the assumption that it cannot happen this is what I
meant: tmp
is not supposed to overflow so part of the condition I had in
place was simply removed.
I reported that exact issue to GCC to make sure it wasn't a bug, and it was indeed confirmed to me that the undefined behaviour of an integer overflow is not limited in scope to whatever insane value it could take: it is apparently perfectly acceptable to mess up the code flow entirely.
While I understand how attractive it can be from an optimization point of view, the paranoid developer in me is straight up terrified by the perspective of a single integer overflow removing security protection and causing such havoc. I've worked several years in a project where the integer overflows were (and probably still are) legion. Identifying and fixing of all them is likely a lifetime mission of several opinionated individuals.
I'm expecting this article to make the rust crew go in a crusade again, and I think I might be with them this time.
Recommend
-
81
Using Lambdas to Simplify Varying Behaviors in Your Code — An excellent article on how lambdas are used to remove condition...
-
52
Cat and mouse become be...
-
23
Five behaviors of great coders With so many people jumping on the data science bandwagon, how can you tell a great coder from the rest?
-
48
Regarding RVO (Return Value Optimization), I think this video gives a real good explanation. Let’s cut to the chase. Check following code: # cat r...
-
4
How COVID-19 Impacted Audience Search BehaviorsIt's your job to understand how to identify and solve disruptions and changes in user search behavior. Here's how trend analysis can help your SEO.
-
6
Xamarin.Forms Behaviors 04/06/2016 2 minutes to read In this article Behaviors lets you add functionality to user interface...
-
8
Now You See Me: How NICE and PDQ plots Uncover Model Behaviors Hidden by Partial Dependence Plots Many machine learning (ML) practitioners use
-
11
December 22, 2020 Git clone: a data-driven study on cloning behaviors @derrickstolee recently
-
3
Getting to know the behaviors of your SDK dependenciesYou likely are using third-party SDKs or libraries in your app. After all, why build functionality from scratch if the building blocks are readily avai...
-
1
Google's Controversial AI Bot Story Keeps Getting More Wild ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK