3 ms·
Seems trivial to bypass just by using `extern "C" fn` or `#[link_name]` attributes, unless you're scanning for those too. But you can get around source scannin
by duped 3y ago
Seems trivial to bypass just by using `extern "C" fn` or `#[link_name]` attributes, unless you're scanning for those too.
But you can get around source scanning too by compiling your code, `include_bytes` the executable, mmap'ing and then calling the entrypoint.
- ghusbands 3y agoSure, what you list may or may not have been missed, but they can all be vetted under the same model. It is possible to make things more automatically secure, step by step.
- duped 3y agoNot really, because the real malicious code can exist out-of-band of the source, and the attack vector is indistinguishable from normal code.
- ghusbands 3y agoThen you fix that attack vector in the same way. People don't have to solve 100% of the problem immediately; it's still an improvement.
- kibwen 3y agoAFAIK the last step is going to require an unsafe block, which is going to be a bright red flag even for people who don't think to grep for include_bytes.
- duped 3y agoUnsafe is hardly a bigger red flag than mmap'ing an opaque blob with PROT_EXEC and then calling a function in it. But the entire pretense of such an attack is that you're not looking at the malicious code. Unsafe is not really a red flag, except for people who don't understand what unsafe means. And like you point out, if you see it, you need to audit the code regardless.
- dgacmu 3y agoThese attacks would be very noticeable in a crate that was not already using unsafe. That's a pretty reasonable start, at least - and it gives a little more benefit to reducing the number of unsafe-using crates you pull in. (For non-rust folks, using mmap requires using unsafe, so you can't map your own machine code in without being explicit about unsafe)
- duped 3y agoThe issue isn't `mmap`, that's just a contrived example to show that scanning source code isn't enough to stop an attacker from adding malicious code to the supply chain. Forbidding unsafe is a big gun. You need unsafe code for any FFI, so attackers will just look for crates that link to system libraries and add their malicious code there. If you want to do any kind of fast iteration over slices/vectors you need to use unsafe to explicitly elide bounds checks. I think the real nugget of truth is that the vulnerability is `cargo update` and that tooling needs to look at changes that happen between versions, and alerting to new unsafe or extern bindings is a good way to do that. But I still see a few obvious ways around it - what you really want is a linker shim that can detect when symbols are being relocated into the final executable that shouldn't be there.
- dgacmu 3y agoAbsolutely. Crates that already use unsafe will be a more attractive target. Most of the ways to sneak arbitrary code execution into rust require unsafe. As I said, it helps. It's not perfect. But there are a lot of crates out there that don't use unsafe, and having a way to focus your attention is useful. Looking at some of my own projects, for example, I notice that I often use crates like "env_logger" with 3.9M downloads. What an absolutely magical target for a supply chain attack -- but it doesn't use unsafe, or net, or tokio, or a lot of other things, and pinning that restriction with Cackle would let me update it with much less worry. I kinda like that. I'm really not arguing that this is a silver bullet. It's just .. nice. Edited to add, as a counterpoint: The "log" crate, which is used by env_logger, _does_ use unsafe. Great target for a supply chain attack -- and perhaps reason to nudge the developers to find ways to get rid of it!