11 ms·
I assume OP s point is that unsoundness or UB in an unsafe block is not contained in that block, but can taint safe code anywhere in the program. Which is true.
by the_duke 6y ago
I assume OP s point is that unsoundness or UB in an unsafe block is not contained in that block, but can taint safe code anywhere in the program. Which is true.
- XMPPwocky 6y agoonly if that block, or something in its "trusted set" (my term, for things in the same module that can access private members) is incorrect, though. safety/unsafety in Rust is factorable, which is a key part of the reason Rust is useful at all.
- vinay_ys 6y agoRest of your program blindly believes that the interface of your "trusted set" is safe because you owned that responsibility when you marked it unsafe. If you have a memory safety bug in that interface, then you can taint the rest of the program's memory safety as well, correct?
- PudgePacket 6y agoYes, that's the whole point though.
- ridiculous_fish 6y agoI think that is too strong. Consider this code: unsafe { libc::fork() }; let v = vec![1]; This may hang or even crash (malloc in the child) but there's no sense in which the unsafe block is "incorrect." Some unsafe code has unavoidable implications for the entire program.
- burntsushi 6y agoIndeed, some uses of unsafe aren't meaningfully factorable. File backed memory maps or shared memory with other processes are other important real world examples that are difficult or impossible to meaningfully factor in the context of a single process. But I still think that saying "safety in Rust is factorable" is accurate beyond a mere first approximation. Figuring out how to encapsulate unsafety is, in my experience, the essential creative aspect to using unsafe at all. Because if safety wasn't something you could encapsulate, then Rust really wouldn't be what it is. (I have spent many long hours thinking about how and to what extent the safety of file backed memory maps could be encapsulated. Which is to say, factoring safety is really the ultimate goal, even if certain things remain beyond that goal.)
- burntsushi 6y agoYes, it's true, but that wasn't what Animats said. And even if that was Animats' point, it doesn't invalidate the GP. The key value proposition of Rust isn't that "you'll never have memory safety bugs," but rather, that if your unsafe code is correct and sound, then safe Rust will be free of memory safety bugs. The important bit is the implication that grants one the power to make that sort of reasoning. It's important precisely because it limits the places in your code that need to be audited.
- tsimionescu 6y agoThis is indeed a very powerful property. However, I have a question: is it a regular practice to ensure that code marked unsafe is actually safe for whichever parameters it receives? Or could the safety of some unsafe code depend on the way its safe wrapper is called?
- burntsushi 6y agoIf you have an unsafe function---that is, a function that is unsafe to call---then it is common practice to document the precise preconditions that the caller must uphold in order to ensure safety. This may indeed include passing a correct parameter. For example, the preconditions of the slice method `get_unchecked` require the caller to verify that the index provided is in bounds, otherwise the behavior is UB. If you have a safe function that uses unsafe internally, then all possible invocations of that function should be safe. If this isn't true, then we call those sorts of APIs unsound and they are strongly discouraged. David Tolnay wrote a great blog post about it: https://docs.rs/dtolnay/0.0.7/dtolnay/macro._03__soundness_bugs.html https://docs.rs/dtolnay/0.0.7/dtolnay/macro._03__soundness_b...
- tsimionescu 6y agoThan you for the details, that makes a lot of sense!