Problem
Summary
This issue was originally identified using Fuzz testing with cargo-fuzz / libfuzzer targeting toml::from_str::<TomlManifest>().
A crafted Cargo.toml file containing a malformed git++:// URL in a [profile] per-package override section causes cargo to panic with called Result::unwrap() on an Err value: RelativeUrlWithoutBase.
Although low severity, this crashes any cargo command (build, check, run, metadata, etc.) before compilation even begins.
Affected Component
- Crate:
cargo-util-schemas
- File:
crates/cargo-util-schemas/src/core/package_id_spec.rs
- Function:
strip_url_protocol() (line 231)
Minimal Reproducer
A 2-line, 32-byte Cargo.toml that panics cargo:
[profile]
Y.package.'git++://x:'=""
Or as a cargo project
$ cat Cargo.toml
[profile]
Y.package.'git++://x:'=""
$
$ cat src/main.rs
//! Minimal reproducer: Cargo.toml profile-override key triggers panic
//! in cargo-util-schemas via strip_url_protocol() unwrap.
//!
//! A crafted [profile] section with a git++-scheme package spec causes
//! PackageIdSpec::parse -> strip_url_protocol -> .parse().unwrap() to
//! panic with RelativeUrlWithoutBase.
fn main() {
let path = std::env::args().nth(1).unwrap_or("malicious-Cargo.toml".into());
let contents = std::fs::read_to_string(&path)
.expect("failed to read file");
println!("=== Parsing: {} ===\n{}\n", path, contents);
let _: cargo_util_schemas::manifest::TomlManifest =
toml::from_str(&contents).unwrap();
}
$
$ cargo run
thread 'main' (274477) panicked at /rustc/5a2be9f5f075d31e3ca5526b5b029881ce441253/src/tools/cargo/crates/cargo-util-schemas/src/core/package_id_spec.rs:231:44:
called `Result::unwrap()` on an `Err` value: RelativeUrlWithoutBase
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$
Backtrace
$ RUST_BACKTRACE=1 cargo run
thread 'main' (274486) panicked at /rustc/5a2be9f5f075d31e3ca5526b5b029881ce441253/src/tools/cargo/crates/cargo-util-schemas/src/core/package_id_spec.rs:231:44:
called `Result::unwrap()` on an `Err` value: RelativeUrlWithoutBase
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/5a2be9f5f075d31e3ca5526b5b029881ce441253/library/std/src/panicking.rs:676:5
1: core::panicking::panic_fmt
at /rustc/5a2be9f5f075d31e3ca5526b5b029881ce441253/library/core/src/panicking.rs:80:14
2: core::result::unwrap_failed
at /rustc/5a2be9f5f075d31e3ca5526b5b029881ce441253/library/core/src/result.rs:1870:5
3: cargo_util_schemas::core::package_id_spec::strip_url_protocol
4: <cargo_util_schemas::core::package_id_spec::PackageIdSpec>::parse
5: <serde_ignored::Deserializer<toml::de::deserializer::value::ValueDeserializer, cargo::workspace::parser::deserialize_toml::{closure#0}> as serde_core::de::Deserializer>::deserialize_option::<serde_core::de::impls::OptionVisitor<alloc::collections::btree::map::BTreeMap<cargo_util_schemas::manifest::ProfilePackageSpec, cargo_util_schemas::manifest::TomlProfile>>>
6: <cargo_util_schemas::manifest::TomlProfile as serde_core::de::Deserialize>::deserialize::<serde_ignored::Deserializer<toml::de::deserializer::value::ValueDeserializer, cargo::workspace::parser::deserialize_toml::{closure#0}>>
7: <serde_ignored::MapAccess<toml::de::deserializer::table::TableMapAccess, cargo::workspace::parser::deserialize_toml::{closure#0}> as serde_core::de::MapAccess>::next_value_seed::<core::marker::PhantomData<cargo_util_schemas::manifest::TomlProfile>>
8: <serde_ignored::TrackedSeed<core::marker::PhantomData<core::option::Option<cargo_util_schemas::manifest::TomlProfiles>>, cargo::workspace::parser::deserialize_toml::{closure#0}> as serde_core::de::DeserializeSeed>::deserialize::<toml::de::deserializer::value::ValueDeserializer>
9: <<cargo_util_schemas::manifest::TomlManifest as serde_core::de::Deserialize>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map::<serde_ignored::MapAccess<toml::de::deserializer::table::TableMapAccess, cargo::workspace::parser::deserialize_toml::{closure#0}>>
10: cargo::workspace::parser::read_manifest
11: <cargo::workspace::workspace::Packages>::load
12: <cargo::workspace::workspace::Workspace>::find_root
13: <cargo::workspace::workspace::Workspace>::new
14: <clap_builder::parser::matches::arg_matches::ArgMatches as cargo::util::command_prelude::ArgMatchesExt>::workspace
15: cargo::commands::run::exec
16: <cargo::cli::Exec>::exec
17: cargo::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
$
Problem
Summary
This issue was originally identified using Fuzz testing with
cargo-fuzz/libfuzzertargetingtoml::from_str::<TomlManifest>().A crafted
Cargo.tomlfile containing a malformedgit++://URL in a[profile]per-package override section causescargoto panic withcalled Result::unwrap() on an Err value: RelativeUrlWithoutBase.Although low severity, this crashes any cargo command (
build,check,run,metadata, etc.) before compilation even begins.Affected Component
cargo-util-schemascrates/cargo-util-schemas/src/core/package_id_spec.rsstrip_url_protocol()(line 231)Minimal Reproducer
A 2-line, 32-byte
Cargo.tomlthat panics cargo:Or as a cargo project
Backtrace