5 ms·
> Rust being advertised as a safe language (which is true) got so much into the user's heads that they think if they write it in Rust it's safe and crash free b
by surajrmal 9y ago
> Rust being advertised as a safe language (which is true) got so much into the user's heads that they think if they write it in Rust it's safe and crash free by default. There are plenty of security/safety bugs that aren't about dereferencing a null or accessing invalid ptr.
> No cynicism intended, just an observation from what I see around.
The difference is what happens when a bug is encountered. If it is caught and panicked upon, then that is safe predictible behavior that cannot be exploited into something like privilege escallation.
- SAI_Peregrinus 9y agoCrash bugs caused by a panic can't necessarily be used for privilege escalation, but they can certainly be used for DOS attacks.
- halayli 9y agoMy point is that privilege escalation can happen from logical bugs
- zerokernel 9y agoPanics can of course result in exploitable system behaviour.
- hedora 9y agoI remember when all the same arguments were made about Java, which led people to ignore the possibility of memory leakage and privilege escalation, even though both those things are common problems with idiomatic Java. For instance: Swing recommends you register callbacks all over the place, but those cause otherwise dereferenced windows to stay live from the GC’s perspective (this is a general problem with the callback pattern, not swing). Java serialization surfaces all sorts of private methods to outside processes via the reflection APIs, which is even easier to exploit than arbitrary memory stomping in C. Practically everything can throw a null pointer exception, and all generics code can throw ClassCastExceptions. Writing all the error handling logic for this is at least as hard as restricting yourself to a memory-safe subset of C++ templates. If you miss an error handling case, an attacker can use that to escalate up to increasingly high level invariant violations in your code. Basic things like “final” have ill-defined semantics with multithreaded code (final fields can change value, even without reflection). I don’t know Rust well enough to know which classes of these bugs it has (and I doubt the Rust community really does either—-it took the Java world a decade to notice some issues like the above). With the exception of the “final” problems, I think fixing any of the things I listed reduces to solving the halting problem, or giving up on using turing complete languages. This makes me skeptical of many claims coming from Rust proponents at the moment.
- steveklabnik 9y agoRust is significantly different with regards to this stuff: * There is no reflection API * Exceptions don't exist * There's no subtyping, so ClassCastExceptions can't exist. (There's subtyping with lifetimes, and you can't cast them, so that doesn't count) * final doens't exist That said, every language has things that you don't realize; we did have a sort of similar moment to this stuff before 1.0 with the "leakapocalypse." Rust will have its own issues. But it doesn't really inherit the problems you're talking about above.
- quotemstr 9y ago> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spelled out. This is one thing Rust did that I do agree was a good move. The other stuff? I remain unconvinced, especially with respect to structural subtyping.
- jimktrains2 9y ago> Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. Can you explain this? Do you mean that the type C does not correctly implement A? Do you mean something that expects a specific value from a methid in A that only B will return? Both of those, while possible just seem like a complaint of "X doesn't prevent me from purposely breaking it".
- dbaupp 9y agoOne example is something like enum A { B, C }: a function might have a precondition that it requires an A::B, and crashes/misbehaves when given an A::C. In Rust, this can be seen in Option::unwrap (requires a Some, panicking if given a None). Technically this is the same sort of thing as in Java, but, at least to me, it seems different/more easily controlled.
- conradev 9y agoPanics may be safe and unwind nicely, but they can still, for example, be triggered in an untested code path to DOS a system. That's one reason that people run AFL against safe Rust.