RUSTSEC-2026-0190 Unsoundness in `Error::downcast_mut()`

Not scored Published

Unsoundness in anyhow's downcast_mut allows undefined behavior and potential memory corruption when modifying error context.

Exploited in the wild
Not known
Login needed
Not needed
Attackable
Not stated
Victim action needed
Not needed
Fix
Available

What is RUSTSEC-2026-0190?

RUSTSEC-2026-0190 is a memory corruption vulnerability in anyhow, published on 25 Jun 2026.

Official description

Affected versions of this crate violate borrow rules, resulting in undefined behavior, when the user adds context to an error via Error::context and then later calls Error::downcast_mut on the returned Error.

The flaw was corrected in commit 6e8c000 by revising how the mutable reference is constructed, avoiding inclusion of a shared reference in the resulting borrow chain.

Example

use anyhow::Error;
use std::fmt;

#[derive(Debug)]
struct ErrorContext(&'static str);

impl fmt::Display for ErrorContext {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

fn main() {
    let mut error = Error::msg("inner error").context(ErrorContext("old context"));
    let context: &mut ErrorContext = error.downcast_mut().unwrap();
    context.0 = "new context";
    println!("{:?}", error);
}

Miri output

error: Undefined Behavior: trying to retag from <1538> for Unique permission at alloc602[0x38], but that tag only grants SharedReadOnly permission for this location
   --> src/ptr.rs:170:18
    |
170 |         unsafe { &mut *self.ptr.as_ptr() }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc602[0x38..0x48]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <1538> was created by a SharedReadOnly retag at offsets [0x38..0x48]
   --> src/ptr.rs:89:18
    |
 89 |             ptr: NonNull::from(ptr),
    |                  ^^^^^^^^^^^^^^^^^^
    = note: stack backtrace:
            0: anyhow::ptr::Mut::<'_, ErrorContext>::deref_mut
                at src/ptr.rs:170:18: 170:41
            1: anyhow::error::<impl anyhow::Error>::downcast_mut::<ErrorContext>
                at src/error.rs:560:18: 560:46
            2: main
                at examples/downcast_mut.rs:15:38: 15:58

Which versions are affected by RUSTSEC-2026-0190?

1 open source package ship an affected version, including anyhow.

PackageAffectedFixed in
anyhow crates.ioFrom 0.0.0-01.0.103

How do I fix RUSTSEC-2026-0190?

Upgrade anyhow to 1.0.103 or later.

Upgrade to the fixed version. Memory-safe languages, compiler hardening and fuzzing prevent most new cases. More about Memory corruption.

Is RUSTSEC-2026-0190 being exploited?

There is no known exploitation of RUSTSEC-2026-0190 in the wild and no public exploit code.

Sources

Is RUSTSEC-2026-0190 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free