{"id":"RUSTSEC-2026-0190","aliases":[],"status":"published","title":"Unsoundness in `Error::downcast_mut()`","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`.\n\nThe 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.\n\n## Example\n\n```rust\nuse anyhow::Error;\nuse std::fmt;\n\n#[derive(Debug)]\nstruct ErrorContext(\u0026'static str);\n\nimpl fmt::Display for ErrorContext {\n    fn fmt(\u0026self, f: \u0026mut fmt::Formatter\u003c'_\u003e) -\u003e fmt::Result {\n        fmt::Display::fmt(\u0026self.0, f)\n    }\n}\n\nfn main() {\n    let mut error = Error::msg(\"inner error\").context(ErrorContext(\"old context\"));\n    let context: \u0026mut ErrorContext = error.downcast_mut().unwrap();\n    context.0 = \"new context\";\n    println!(\"{:?}\", error);\n}\n```\n\n## Miri output\n\n```\nerror: Undefined Behavior: trying to retag from \u003c1538\u003e for Unique permission at alloc602[0x38], but that tag only grants SharedReadOnly permission for this location\n   --\u003e src/ptr.rs:170:18\n    |\n170 |         unsafe { \u0026mut *self.ptr.as_ptr() }\n    |                  ^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc602[0x38..0x48]\n    |\n    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental\n    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information\nhelp: \u003c1538\u003e was created by a SharedReadOnly retag at offsets [0x38..0x48]\n   --\u003e src/ptr.rs:89:18\n    |\n 89 |             ptr: NonNull::from(ptr),\n    |                  ^^^^^^^^^^^^^^^^^^\n    = note: stack backtrace:\n            0: anyhow::ptr::Mut::\u003c'_, ErrorContext\u003e::deref_mut\n                at src/ptr.rs:170:18: 170:41\n            1: anyhow::error::\u003cimpl anyhow::Error\u003e::downcast_mut::\u003cErrorContext\u003e\n                at src/error.rs:560:18: 560:46\n            2: main\n                at examples/downcast_mut.rs:15:38: 15:58\n```","facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"published":"2026-06-25T12:00:00Z","modified":"2026-06-29T14:15:03Z","fixes":[{"ecosystem":"crates.io","package":"anyhow","fixed_in":["1.0.103"],"sources":["osv"]}],"affected":[{"source":"osv","ecosystem":"crates.io","package":"anyhow","ranges":[{"type":"SEMVER","events":[{"introduced":"0.0.0-0"},{"fixed":"1.0.103"}]}]}],"references":[{"url":"https://crates.io/crates/anyhow","tags":["package"]},{"url":"https://rustsec.org/advisories/RUSTSEC-2026-0190.html","tags":["advisory"]},{"url":"https://github.com/dtolnay/anyhow/issues/451","tags":["report"]}],"sources":{"osv":[{"id":"RUSTSEC-2026-0190","title":"Unsoundness in `Error::downcast_mut()`","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`.\n\nThe 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.\n\n## Example\n\n```rust\nuse anyhow::Error;\nuse std::fmt;\n\n#[derive(Debug)]\nstruct ErrorContext(\u0026'static str);\n\nimpl fmt::Display for ErrorContext {\n    fn fmt(\u0026self, f: \u0026mut fmt::Formatter\u003c'_\u003e) -\u003e fmt::Result {\n        fmt::Display::fmt(\u0026self.0, f)\n    }\n}\n\nfn main() {\n    let mut error = Error::msg(\"inner error\").context(ErrorContext(\"old context\"));\n    let context: \u0026mut ErrorContext = error.downcast_mut().unwrap();\n    context.0 = \"new context\";\n    println!(\"{:?}\", error);\n}\n```\n\n## Miri output\n\n```\nerror: Undefined Behavior: trying to retag from \u003c1538\u003e for Unique permission at alloc602[0x38], but that tag only grants SharedReadOnly permission for this location\n   --\u003e src/ptr.rs:170:18\n    |\n170 |         unsafe { \u0026mut *self.ptr.as_ptr() }\n    |                  ^^^^^^^^^^^^^^^^^^^^^^^ this error occurs as part of retag at alloc602[0x38..0x48]\n    |\n    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental\n    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information\nhelp: \u003c1538\u003e was created by a SharedReadOnly retag at offsets [0x38..0x48]\n   --\u003e src/ptr.rs:89:18\n    |\n 89 |             ptr: NonNull::from(ptr),\n    |                  ^^^^^^^^^^^^^^^^^^\n    = note: stack backtrace:\n            0: anyhow::ptr::Mut::\u003c'_, ErrorContext\u003e::deref_mut\n                at src/ptr.rs:170:18: 170:41\n            1: anyhow::error::\u003cimpl anyhow::Error\u003e::downcast_mut::\u003cErrorContext\u003e\n                at src/error.rs:560:18: 560:46\n            2: main\n                at examples/downcast_mut.rs:15:38: 15:58\n```","status":"published","published":"2026-06-25T12:00:00Z","modified":"2026-06-29T14:15:03.650725453Z","updated_at":"2026-11-02T15:53:40.430679Z"}]}}
