Hacker News new | past | comments | ask | show | jobs | submit login

Rust doesn't check for overflow in arithmetic operations in release mode so there are lot of opportunities to create vulnerabilities in Rust.



There is some important context missing from your comment here. At least two points anyway:

In Rust, overflow is not undefined behavior (neither signed nor unsigned). Today, arithmetic wraps in release mode (panics in debug mode), but it may panic in release mode in the future.

The other point is that, since overflow wraps, that may indeed result in logic bugs. And in theory that logic bug could be used to lead to exploit, such as a buffer overrun. But Rust uses bounds checking by default everywhere, so the worst case you'll usually end up with here is a panic or a DoS vulnerability. Not great, but probably preferable to other types of vulns that grant access to sensitive data.

So I think two things would need to happen, at minimum, to get a non-DoS vulnerability here. You'd need to find a bug that caused arithmetic to overflow where it otherwise shouldn't, and you need to find some way to connect that to an explicitly `unsafe` unchecked access into memory.


An other thing to note is that java does not check for overflow either. Having the “native” langage be no worse than the “managed” one is a better situation to be in than the reverse.

Also Rust allows enabling overflow checking in release, it’s a perfectly valid configuration.


>You'd need to find a bug that caused arithmetic to overflow where it otherwise shouldn't, and you need to find some way to connect that to an explicitly `unsafe` unchecked access into memory.

Yes, it's particularly a dangerous problem when doing FFI. Eg you have a `data: &[u8]` and you need to call `extern "C" fn foo(data: *const u8` and `data_len_in_bits: usize)`, you could write `data.len() * 8` for the second parameter and Rust wouldn't stop you.

It's also annoying that the only way to do checked arithmetic is replace all the simple arithmetic operators with `.checked_*()?` function calls. libstd doesn't have a `std::num::Checked<T>` like it has `Wrapping` that would implement all the arithmetic traits in terms of `checked_*` and return `Result<>`. But at least it's not hard to do yourself. ( https://github.com/Arnavion/terminal/blob/475d917377eea43b52... )


Beyond the above, IIRC Android ships with integer overflow enabled (but can't find where I read this).


You can confirm it by looking into the source code:

https://android.googlesource.com/platform/build/soong/+/refs...

Not an expert, but a file named "global.go" makes me confident :).


Amusing to see that the compiler flags for Rust are stored in a Go file ;)


Not that it's important, but just a note that unless you recompile the standard library yourself, integer overflow will still be off for that code since it ships compiled. (Correct me if I'm wrong, that's my recollection).


The Android project compiles the standard library themselves: https://android.googlesource.com/platform/prebuilts/rust/+/a...


Figures, thanks.


Wrapping arithmetic operations have been a reason of vulnerabilities in Linux kernel though. Developers need real addition, not addition modulo 2^32.


I don't understand if you're disagreeing with me or writing something that you think is inconsistent with what I said. Because I don't see anything inconsistent between what I said and what you wrote.


This is how I discovered that one of my code was "bugged". I had to implement a driver for an obscure chinese-made machine with a documentation google translated. In the protocol, there was a check byte and the explanation says that it was the 100 modulo of the sum of all previous byte. They didn't mention overflow. I tested it using a release build and it was working. Later on, while changing a few thing, I notice that the debug build was not working. I quickly find that this was because of the overflow behavior.


If you want to check for overflow, then you can use the methods that explicitly check for overflow:

https://doc.rust-lang.org/std/primitive.u32.html#method.chec...

So this is not an issue at all.


They are long to type and hard to read. They are so inconvenient to use that nobody uses them, even developers of Rust. Take source code of Vec as an example [1]. They use wrapping addition instead of checked one.

For comparison, in Swift normal arithmetic operations check for overflow.

[1] https://doc.rust-lang.org/src/alloc/vec/mod.rs.html#1773




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: