cargo audit in a project of mine today to discover that my Cargo.lock included version 0.22.0 of the nix crate, which has a memory corruption vulnerability (RUSTSEC-2021-0119). This was strange, because a fix had been published in nix version 0.22.2 for almost a month; I'd run
cargo update recently; and rustyline 9.0.0, the dependency that was pulling nix in, specified it as
nix = "0.22", not
nix = "=0.22.0".
It took me a while to figure out what was going on. An empty crate with only
rustyline = "9.0" in its dependencies got nix 0.22.2, but I eventually found that if bitflags >= 1.3.0 ended up somewhere in the dependency graph, nix got downgraded to 0.22.0.
nix 0.22.0 had a dependency
bitflags = "1.1", and bitflags 1.3.0 broke compatibility with certain old versions of rustc that nix aimed to support, so the author added a "< 1.3.0" version bound to bitflags in nix 0.22.1. Cargo therefore seems to see that if bitflags 1.3.x and nix 0.22.x are both needed, the only way to avoid pulling in a version of bitflags in the 1.1 to 1.2 range alongside one in the bitflags 1.3 range is to use the broken nix 0.22.0. It's clever, but it leads to a vulnerable version of nix being silently chosen.
I don't necessarily have solutions, and I'm not affected by the vulnerability, I just thought it might be wise to bring this case to the attention of the people who work on Cargo. A warning would be nice, and I wouldn't consider an error unreasonable here if the "no multiple versions of a crate within the same compatibility range" rule is non-negotiable. Cargo automatically downgrading crates to potentially buggy versions due to distant interactions with other crates just doesn't seem right to me.