3 ms·
If code in an unsafe block triggers undefined behavior, then the assumptions the compiler makes regarding safety will no longer be true, and purely safe code (c
by ndiddy 5mo ago
If code in an unsafe block triggers undefined behavior, then the assumptions the compiler makes regarding safety will no longer be true, and purely safe code (code with no unsafe blocks) is no longer guaranteed to be safe. This is what's happening in the example the person on Github wrote in the issue.
- weinzierl 5mo agoExactly and "[...]and purely safe code (code with no unsafe blocks) is no longer guaranteed to be safe" hits the nail on the head. I take issue with the phrasing of OP's title: "allows for UB in safe rust". AFAIK there are compiler bugs that allow UB in safe Rust, but this is not what is happening here. We have UB in an unsafe block (which is to be expected) which enables an issue outside in safe code. What is your opinion? Is calling this "UB in safe Rust" justified?
- mswphd 5mo agoit is, but it's a little confusing here because the library/consumer of the library are the same person. This is a bug in the library, namely in Bun's PathString implementation. The bug is a soundness issue, precisely because usage of Bun's PathString implementation allows for UB in safe rust. Now this buggy library isn't that big of a concern for the community, because Bun is the only consumer. It's not also an indication of a compiler bug, because Bun's library is implemented using unsafe rust. But the fundamental issue is that usage of Bun's PathString implementation allows for UB in safe rust, and is therefore (clearly) unsound.
- fc417fc802 5mo agoSuppose I initialize something in an unsafe block. I promise the compiler that it's properly initialized, but in reality it isn't. Importantly I never make use of the garbage values in the unsafe block so no UB has occurred - yet. Later, the garage enters otherwise safe machinery and triggers UB. UB has now happened in safe rust as a result of my earlier contractual violation. You can extend this example to other scenarios where UB in unsafe begets further UB in safe later on.
- tialaramex 5mo agoActually I think Rust says UB has occurred if you return a T which isn't properly initialized. For example if you unsafely MaybeUninit<u32>::assume_init() then Rust says that's UB even though all possible bit patterns for u32 are valid. This is because that's not going to emit any machine code at all, and yet it will cause LLVM to do very nasty things, for example code which either prints "Odd" or "Even" by examining the integer may now print neither because that's faster and this uninitialized integer isn't odd, yet it also isn't even so...
- tialaramex 5mo agoI'd prefer the phrasing "UB from safe Rust". The UB is† always in the Unsafe Rust, but that's not necessarily a problem, the problem was that we caused it from our safe Rust and that's definitely not OK. † Soundness bugs are known to exist in Rust, but for the known ones you have to be really asking for it, so it's not plausible that they'd impact you by accident.