Skip to content

cargo panics on crafted Cargo.toml with malformed git URL in profile package override #17459

Description

@gkamathe

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.
$ 

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: bugS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions