diff --git a/crates/eyre/RUSTSEC-0000-0000.md b/crates/eyre/RUSTSEC-0000-0000.md new file mode 100644 index 0000000..81aa4ab --- /dev/null +++ b/crates/eyre/RUSTSEC-0000-0000.md @@ -0,0 +1,41 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "eyre" +date = "2024-03-05" +url = "https://github.com/eyre-rs/eyre/issues/141" +categories = ["memory-corruption"] + +[versions] +patched = [">= 0.6.12"] +unaffected = ["< 0.6.9"] + +[affected] +functions = { "eyre::Report::downcast" = [">= 0.6.9, < 0.6.12"] } +``` + +# Parts of Report are dropped as the wrong type during downcast + +In affected versions, after a `Report` is constructed using `wrap_err` or +`wrap_err_with` to attach a message of type `D` onto an error of type `E`, then +using `downcast` to recover ownership of either the value of type `D` or the +value of type `E`, one of two things can go wrong: + +- If downcasting to `E`, there remains a value of type `D` to be dropped. It is + incorrectly "dropped" by running `E`'s drop behavior, rather than `D`'s. For + example if `D` is `&str` and `E` is `std::io::Error`, there would be a call of + `std::io::Error::drop` in which the reference received by the `Drop` impl does + not refer to a valid value of type `std::io::Error`, but instead to `&str`. + +- If downcasting to `D`, there remains a value of type `E` to be dropped. When + `D` and `E` do not happen to be the same size, `E`'s drop behavior is + incorrectly executed in the wrong location. The reference received by the + `Drop` impl may point left or right of the real `E` value that is meant to be + getting dropped. + +In both cases, when the `Report` contains an error `E` that has nontrivial drop +behavior, the most likely outcome is memory corruption. + +When the `Report` contains an error `E` that has trivial drop behavior (for +example a `Utf8Error`) but where `D` has nontrivial drop behavior (such as +`String`), the most likely outcome is that downcasting to `E` would leak `D`.