3 ms·
The rabbit hole of unsafe Rust bugs
- Alifatisk 3y agoAre there examples where unsafe Rust is a must?
- pohl 3y agoThe 3rd paragraph has 3 bullet points about it.
- Alifatisk 3y agoI know, but I'd like to read some input from the HN crowd aswell.
- Ygg2 3y agoSure. Accessing C FFI. Calling low level code like asm!, SIMD and so on. You'll never be able to truly escape it, just mostly. -- One interesting suggestion by matthieum on Reddit was to make previously safe fn unsafe.
- rowanG077 3y agoThere quite a few APIs which do not have safe wrappers. Recently I needed to disable IP fragmentation on a socket. I had to invoke the raw c library which is unsafe.
- ostenning 3y agoDMA, because the buffer can be linked to a designated RAM section, and it needs to be declared as a static mutable. There would be many examples when code is running at lower levels with no OS abstraction
- tmtvl 3y agoI wonder if it would be interesting to introduce a "safe" annotation to Rust, which would fail compilation if any code the function calls is unsafe.
- technion 3y agoYou can use #![deny(unsafe_code)] in your own code. If you're hoping to enforce across all called functions, it's likely to be unworkable since a lot of stdlib ends up calling unsafe code.
- pitaj 3y agoOr even stronger #![forbid(unsafe_code)] Then it can't be `#[allow()]`ed. There's also things like `cargo gieger` that will tell you how much unsafe code your dependencies have.
- junon 3y agoTIL forbid(), thanks!
- giovannibonetti 3y agoI think you meant `cargo geiger`
- im3w1l 3y ago> a bug in safe code can easily cause unsound behavior in your unsafe code if you’re not careful. I thought the whole point of safe code was that any bugs in safe code cannot cause unsound behaivor, so it's on the unsafe code to maintain soundness even if it's used incorrectly by safe code?
- hedora 3y agoYes; that's the whole point. There is even a computer verified proof that (for some version of std) if you only use the standard library and don't use unsafe, then you can't write a program that exhibits unsound behavior. Of course, if there's one bug in unsafe code, then all bets are off, but that's still a bug in the unsafe code.
- remexre 3y agoI think the "It’s not unsound; it’s not even incorrect." is wrong... Clearly, it's unsound -- the problem in this post was documented[0] as a safety precondition of the one function they call in that block! In code I'd consider high-quality, there'd be a comment like this [1]: // SAFETY: inner is only mutated by foo, bar, and baz, all of which // ensure the pointer is valid. [0]: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref https://doc.rust-lang.org/std/primitive.pointer.html#method.... [1]: https://std-dev-guide.rust-lang.org/policy/safety-comments.html https://std-dev-guide.rust-lang.org/policy/safety-comments.h...
- hedora 3y ago[0] has an unsafe annotation, so in order to invoke it, you have to write the token "unsafe", which means all bets are off unless some sort of external proof of soundness exists.
- remexre 3y agoThe "It's" in the quote (from the article) was referring to a particular snippet in the article, not the .as_ref() method.
- juliangmp 3y agoMinor nitpick, at the end of the article: Sure, it does some risky pointer math, but that’s considered safe in Rust. I wouldn't fully agree to that, from The Rust Programming Language book [1]: Much of Rust’s safety comes from compile-time checks, but raw pointers don’t have such guarantees, and are unsafe to use. [1] https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/raw-pointers.html https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/sh...
- rstuart4133 3y agoI am Rust newbie myself, but I don't understand how this could be considered safe: strict::with_metadata_of(new_ptr, self.shared.as_ptr() as *mut T) I always thought pointer math was considered safe because math is safe. Which is fair enough, as adds and subtractions can't do much beyond overflow. What is unsafe is accessing the memory location using the result of that math, as the result could point anywhere. They don't do that (access memory using the raw pointer) here. But if anything what does happen is worse: raw pointer that is considered unsafe to use is cast back to a typed pointer that is considered safe to use, and returned to the unsuspecting caller. I'm scratching my head on why strict::with_metadata_of() isn't marked as unsafe. In the example the standard library documentation gives https://doc.rust-lang.org/std/primitive.pointer.html#method.with_metadata_of https://doc.rust-lang.org/std/primitive.pointer.html#method.... it is wrapped in unsafe{}.
- steveklabnik 3y agowith_metadata_of returns a raw pointer, which is not safe to use.
- rstuart4133 3y agoThanks for taking the time to point out the obvious to a newbie. Now, that's apparent the point of the article isn't so clear. The point looks to revolve around this line: > Eagle-eyed readers might have noticed that this code has no unsafe. Not even a line. That statement is not really true, as the return type (*T) implies the method is unsafe. Oh well, it was an interesting bug hunt story.