Hacker News new | ask | show | jobs
by jacquesm 3044 days ago
Let me give you one example of how this could lead to exactly such a scenario:

An integer that has wrapped gets passed into a piece of unsafe Rust code that was otherwise bullet proof, exposing a vulnerability where otherwise the program would have abended much earlier when the overflow happened.

The very best spot to trap an error is where it is first initiated, any cycles after that point are being run in what is essentially an undefined state which will sooner or later - hopefully sooner, but sometimes much later - result in either incorrect behavior, a security issue or in the most benign cases a crash. To willfully postpone the discovery of the error introduces the risk that the error will never be caught at all, the program will continue to run and will produce bogus output, spill out your state secrets or worse.

First make it work correctly, then make it fast. If you're going to worry about speed before you have it working you are falling headlong into the premature optimization trap, a trap that C programmers the world over unfortunately have extensive experience with and that I thought - perhaps mistakenly so - the Rust crowd was trying to address.

Btw, Swift seems to get this right, I wonder what their secret sauce is.

2 comments

> An integer that has wrapped gets passed into a piece of unsafe Rust code that was otherwise bullet proof, exposing a vulnerability where otherwise the program would have abended much earlier when the overflow happened.

In that case, that piece of unsafe code would have a bug, which would be a bug regardless of whether overflow happened. The contract of unsafe code is that it must not expose undefined behavior.

For example, vector indexing is implemented with unsafe code, but the unsafe code performs bounds checks, so it doesn't matter whether an overflowed integer was passed in as the index.

> Btw, Swift seems to get this right, I wonder what their secret sauce is.

Their "secret sauce" is not having the same performance goals (which is not a criticism of Swift).

> An integer that has wrapped gets passed into a piece of unsafe Rust code

Yes. That still requires unsafe code. All bets are off there. You should be validating everything with regards to unsafe. There's tons of ways unsafe can go wrong; this scenario is a drop in the bucket. The bug is fundamentally in that unsafe code, not in the overflowed integer, as unsafe code is not supposed to expose memory unsafety; you could have passed a zero or a -128 or whatever manually, and it would still have caused this.

> The very best spot to trap an error is where it is first initiated,

I agree completely!

> I thought - perhaps mistakenly so - the Rust crowd was trying to address.

If you believed that Rust was about program correctness above all else, then yes, you were mistaken. As I said above, our priorities are memory safety above all else. Correctness is certainly up there, but when the rubber hits the road, hard choices have to be made.

Ok, in that case thank you for the correction, it helps to place Rust a little bit more accurate on my mental map of programming languages.

Btw, and on the same note, I always felt that it should be possible to generate a fault on an unexpected carry so I see this as much as a CPU issue as a programming language issue.

No worries! That discrepancy might explain why we've occasionally butted heads in the past with regards to the language :)