5 ms·
> Rust had a chance to fix this, but also dropped the ball. By default, a Rust project will panic on integer overflow in debug builds and will overflow on rele
by shepmaster 4y ago
> Rust had a chance to fix this, but also dropped the ball.
By default, a Rust project will panic on integer overflow in debug builds and will overflow on release builds. Two key points to note, however:
1. You can change the setting so that your project panics in release or overflows in debug mode.
2. We reserved the right to change the default at some point in the future. This will probably be widely communicated before it ever happens, and last I heard we are still waiting for the cost of performing those checks to be "reasonable" before thinking about making such a change.
- kibwen 4y agoFurthermore, because integer overflow is defined behavior, the integer overflow is never considered a root cause in Rust. In order for an integer overflow to express as UB in Rust, you'd have to use it in conjunction with an `unsafe` block that was failing to ensure its invariants, and that would be considered the root cause. If you're not using `unsafe`, then an integer overflow is at worst a logic bug.
- p4l4g4 4y agoA logic bug can be dangerous too though. E.g. Bumping a user ID, to get a "fresh" one or calculate port to open based on offset. When not bounded to a known range, this kind of logic can easily pose a serious security risk. Most of the time, it will probably just work, but under extreme conditions, it will fail. If your language at least catch the overflow and crash instead of wrapping around, you "only" have a denial of service. Can imagine that implementing bounds checking can be costly, when done in software. Wonder if there are any hardware improvements that could reduce risk in this area.
- wongarsu 4y agoIf you identify an area as risky, it's trivial in Rust to do a checked_add or saturating_add. The challenge is obviously identifying this, but having easy library functions anectotally leads to people looking for it in code reviews.
- kibwen 4y agoIndeed, nobody ever said that logic bugs were good, but as a category of flaw it means that integer overflow in Rust isn't particularly interesting compared to all the other innumerable ways to introduce logic bugs. And I say that as someone who wouldn't really mind if the behavior was changed to panic-by-default in release mode.
- astrange 4y agoA logic bug can be just as bad as any other kind of bug. Security bugs/memory corruption don't always deserve the extra special treatment they get, nor are they the only kind of remotely exploitable issue.
- CorrectHorseBat 4y ago> I heard we are still waiting for the cost of performing those checks to be "reasonable" before thinking about making such a change. What I don't understand is, checking for integer overflow is extremely cheap in hardware, so why is there any cost for performing those checks? What am I missing?
- kelnos 4y agoPresumably the program has to check bit in a status register or something like that to tell if the previous instruction caused overflow, no? That means an extra branch after each arithmetic instruction. I imagine that's not cheap?
- dahfizz 4y agoInteger arithmetic is a significant part of ~every program. A single branch that checks the overflow flag is not expensive. But branching on that flag every time you do integer math is death by a billion paper cuts.
- CorrectHorseBat 4y agoYour could use interrupts, no? Basically free when not triggered and when triggered you probably don't care about performance anymore.
- prbs23 4y agoMost architectures do not provide an interrupt that is generated by an integer overflow. Since this would be a significant architectural change in the hardware, it can't be simply added in. Additionally, if you are running inside an operating system, handling an interrupt usually incurs a trip through the kernel, which would add extra overhead every time an overflow did happen. Since there's a lot of software which depends on integers overflowing, this overhead on each overflow could significantly impact legacy software.
- CorrectHorseBat 4y ago
- travisgriggs 4y agoFascinating. Haven't had a chance to do Rust yet, but I think I would change this so that they were consistent. I do embedded, and that kind of "behaves differently in different places" is the worst kind of bug to figure out.
- kibwen 4y ago> behaves differently in different places It doesn't behave differently in different places, it differs based on build profile. You test in debug mode, which is where overflows will panic, which makes them quite obvious. If you want to pay the price of overflow checks everywhere in release mode, then you can turn them on there as well (it's not that much of a performance penalty, but that might not be true on embedded...). It's effectively just a compiler flag.
- eklitzke 4y agoJust in case people don't know, you can get the same behavior with C or C++ by invoking GCC or Clang with -ftrapv. I don't know about Rust, but for C and C++ -ftrapv will only fault on signed integer overflow, as signed integer overflow is UB in C/C++ but unsigned integer overflow is well defined (it's guaranteed to wrap around to zero on all platforms). So even if you're trapping on integer overflow, there are still plenty of weird things that can happen if you unintentionally overflow an unsigned integer.