Live data from Hacker News

Pitfalls of Safe Rust

corrode.dev

71–80 of 145 posts

Re: Pitfalls of Safe Rust

#71

Earlier quoted context omitted.

Unfortunately, operator[] on std::vector is inherently unsafe. You can potentially try to ban it (using at() instead), but that has its own problems. There’s a great talk by Louis Brandy called “Curiously Recurring C++ Bugs at Facebook” [0] that covers this really well, along with std::map’s operator[] and some more tricky bugs. An interesting question to ask if you try to watch that talk is: How does Rust design aro…

Thank you for sharing. Seems I still have more to learn! It seems the bug you are flagging here is a null reference bug - I know Rust has Optional as a workaround for “null” Are there any pitfalls in Rust when Optional does not return anything? Or does Optional close this bug altogether? I saw Optional pop up in Java to quiet down complaints on null pointer bugs but remained skeptical whether or not it was better to…

It's not so much Optional that deals with the bug. It's the fact that you can't just use a value that could possibly be null in a way that would break at runtime if it is null - the type system won't allow you, forcing an explicit check. Different languages do this in different ways - e.g. in C# and TypeScript you still have null, but references are designated as nullable or non-nullable - and an explicit comparison to null changes the type of the corresponding variable to indicate that it's not null.

Re: Pitfalls of Safe Rust

#72

Earlier quoted context omitted.

That was my first impression as well. So much of Rust’s language and standard library enforces correctness, that gaps start to feel way more visible. “as” is a good example. Floats are pretty much the only reason PartialEq exists, so why can’t we have a guaranteed-not-NaN-nor-inf type in std and use that everywhere? Why not make wrapping integers a panic even in release mode? Why not have proper dependent types (e.g.…

The other option would be to change how floating point works. IEEE specifies operations, not names, so it would be totally valid to have <= on floats be a total order (using integer cpu instructions), and make a function called IEEEAreIdiotsWhoThinkThisIsFloatingPointLessThan which is the partial order that sucks.

[deleted]

Re: Pitfalls of Safe Rust

#73
post #2

Is "as" an uneccesary footgun?

I wouldn't say so. I quite like "as". It can have sharp edges but I think the language would be significantly worse off without it.

It's useful to have something that does the job of "as", but I dislike how the most dangerous tool for type conversions has the nicest syntax.

Most of the time I want the behavior of ".try_into().unwrap()" (with the compiler optimizing the checks away if it's always safe) or would even prefer a version that only works if the conversion is safe and lossless (something I can reason about right now, but want to ensure even after refactorings). The latter is really hard to achieve, and ".try_into.unwrap()" is 20 characters where "as" is 2. Not a big deal to type with autocomplete, but a lot of visual clutter.

Re: Pitfalls of Safe Rust

#74
post #2

Is "as" an uneccesary footgun?

That was my first impression as well. So much of Rust’s language and standard library enforces correctness, that gaps start to feel way more visible. “as” is a good example. Floats are pretty much the only reason PartialEq exists, so why can’t we have a guaranteed-not-NaN-nor-inf type in std and use that everywhere? Why not make wrapping integers a panic even in release mode? Why not have proper dependent types (e.g.…

Some of these don't strike me as particularly pragmatic. E.g. are overflow checks really that expensive, given that it's a well-known footgun that is often exploitable? Sure, you don't want, say, 10% overhead in your number-crunching codec or whatever, but surely it's better to have those cases opt in for better perf as needed, as opposed to a default behavior that silently produces invalid results?

Re: Pitfalls of Safe Rust

#75

Earlier quoted context omitted.

Safe Rust code doesn't have accidental remote code execution. C++ often does. C++ people need to stop pretending that "safety" is some nebulous and ill-defined thing. Everyone, even C++ people, shows perfectly damn well what it means. C++ people are just miffed that Rust built it while they slept.

Research I've seen seems to say that 70-80% of vulnerabilities come from memory safety problems[0]. Eliminating those is of course a huge improvement, but is rust doing something to kill the other 20-30%? Or is there something about RCE that makes it the exclusive domain of memory safety problems? [0] For some reason I'm having trouble finding primary sources, but it's at least referenced in ex. https://security.goog…

Rust also provides guarantees that goe beyond mere memory safety. You get data-race safety as well, which avoids certain kinds of concurrency issues. You also get type-safety which is a step up when it comes to parsing untrusted input, at least compared to C for example. If untrusted inout can be parsed into your expected type system, it's more likely to not cause harm by confusing the program about what's in the variables. Rust doesn't straight up eliminate all source of error, but it makes major strides forward in areas that go beying mere memory safety.

Re: Pitfalls of Safe Rust

#76
post #17

Earlier quoted context omitted.

Compared to C/C++ "as" feels so much safe r. Now that Rust and we the programmers have evolved with it, I too feel that "as" for narrowing conversion is a small foot gun.

I'm struggling to see how you would implement narrowing conversion in a way that is harder for programmers to misuse when they aren't being mindful, while also being pleasant to use when you really do want to just drop higher bits. Like, you could conceivably have something like a "try_narrow" trait which wraps the truncated value inside an Err when it doesn't fit, and it would probably be harder to accidentally misu…

let foo: u8 = bar.truncate_to()?

Re: Pitfalls of Safe Rust

#77

> Overflow errors can happen pretty easily No they can’t. Overflows aren’t a real problem. Do not add checked_mul to all your maths. Thankfully Rust changed overflow behavior from “undefined” to “well defined twos-complement”.

The vast majority of code that does arithmetic will not produce a correct result with two's complement. It is simply assuming that the values involved are small enough that it won't matter. Sometimes it is a correct assumption, but whenever it involves anything derived from inputs, it can go very wrong.

Re: Pitfalls of Safe Rust

#78

Earlier quoted context omitted.

The other option would be to change how floating point works. IEEE specifies operations, not names, so it would be totally valid to have <= on floats be a total order (using integer cpu instructions), and make a function called IEEEAreIdiotsWhoThinkThisIsFloatingPointLessThan which is the partial order that sucks.

For purposes of sorting, Rust does offer a non-IEEE order as f64::total_cmp. You can easily build a wrapper type that uses that for all comparisons, or use a crate that does it for you https://doc.rust-lang.org/std/primitive.f64.html#method.tota...

total_cmp is precisely IEEE's separately specified total order for floats. It's just that the more common operators do something different, and that's perhaps better for most uses where NaN are inherently unexpected and generally indicate that some kind of error condition has occurred.

Re: Pitfalls of Safe Rust

#79

> Overflow errors can happen pretty easily No they can’t. Overflows aren’t a real problem. Do not add checked_mul to all your maths. Thankfully Rust changed overflow behavior from “undefined” to “well defined twos-complement”.

I'm a big fan of liberal use of saturating_mul/add/sub whenever there is a conceivable risk of coming withing a couple orders of magnitude of overflow. Or checked_*() or whatever the best behavior in the given case is. For my code it happens to mostly be saturating.

Overflow bugs are a real pain, and so easy to prevent in Rust with just a function call. It's pretty high on my list of favorite improvements over C/C++

Re: Pitfalls of Safe Rust

#80
post #8

Golang might be better for writing robust software, if that is the goal. Robust services that don't go down.

That's a weird thing to say about a language that doesn't have null safety.

Not to be outdone here, Go introduces multiple null values that are considered distinct, yet they all exhibit the same problem.
Post reply on HN