3 ms·
Talking about `unsafe` in this context seems like changing the discussion completely. All of the concerning things done in the JS supply-chain attacks can be d
by jhugo 5y ago
Talking about `unsafe` in this context seems like changing the discussion completely.
All of the concerning things done in the JS supply-chain attacks can be done perfectly well in safe Rust. You don't need `unsafe` to exfiltrate secrets or to encrypt or delete files.
Auditing the use of unsafe in dependencies is worthwhile for mostly unrelated reasons; it's not the same thing as sandboxing them, auditing them for malicious code, or assessing how much you trust them.
- josephg 5y agoRight; I'm skipping ahead and imagining an alternate universe standard library for rust with capability support. Like, what if we did the thing I proposed in this blog post, but did it to rust instead of javascript? How would that work? In that world, all the privileged operations (filesystem, OS, etc) in std would require an extra capability object to be passed at runtime. The capability would grant permission to the caller to perform the privileged action (like writing to a file). That would stop rogue rust crates from making syscalls that they shouldn't be making. There might also be a way to enforce those permissions at compile time instead of at runtime. But even if we were willing to do that, it wouldn't matter if any library could still use unsafe blocks. The reason is that there's dozens of ways to make syscalls from unsafe blocks without needing to go through std. For example, you could dynamically execute methods in glibc / musl, use an asm! block, or (probably) manually compile a function into a byte array, transmuting it into a function pointer and then execute it. If you changed std, and also banned 3rd party libraries code from using unsafe you could probably make the system secure. But I'm worried that the rust community might not be willing to pay that cost for extra security.
- zozbot234 5y ago> There might also be a way to enforce those permissions at compile time instead of at runtime. AIUI, a compile time capability is just a custom unit type, perhaps using PhantomData to depend at compile time on some generic type or consteval parameter. Then ordinary type checking is enough to ensure that this gets "threaded" correctly throughout the code, as required. 'Narrowing' a capability is just a one-way type conversion, e.g. via .into(). Since you're doing this via a unit type that carries no information, everything should disappear at runtime, with no effects on the ABI. You'd effectively be using the type checker to prove things about what your code is allowed to do. (It turns out that there's a (2021) article expanding on this: https://www.hardmo.de/article/2021-03-14-zst-proof-types.md https://www.hardmo.de/article/2021-03-14-zst-proof-types.md )
- ryukafalz 5y ago> I'm skipping ahead and imagining an alternate universe standard library for rust with capability support. FWIW there is https://github.com/bytecodealliance/cap-std https://github.com/bytecodealliance/cap-std (…but yes it’s more limited than what you’re thinking of)
- jhugo 5y ago> If you changed std, and also banned 3rd party libraries code from using unsafe you could probably make the system secure. But I'm worried that the rust community might not be willing to pay that cost for extra security. Anyone will be willing to pay a cost when the benefit is well-defined and exceeds that cost. "Make the system secure" doesn't have a well-defined meaning, because security isn't binary like that. Banning `unsafe` from all non-std deps is pretty hard for most real-world Rust software unless std grows a lot larger. Even apart from domains with a lot of necessary unsafe, like embedded, you have crates like `bytes` or `tokio` that use unsafe for performance reasons. A realistic discussion about this stuff always has to involve trust. I don't have much issue with tokio containing unsafe, given its track record and the quality of the code. OTOH, I don't allow actix in my dependency trees because its history of using unsafe unnecessarily and unsoundly means that I don't trust it. To me, a more interesting approach for improving supply chain security in software builds on the issue of trust rather than things like technical capabilities. Rust has some interesting work in this area already, like cargo-crev for distributed code review, cargo-deny for applying rules to your dependency tree, cargo-geiger for seeing which dependencies are using unsafe, etc.