diff --git a/crates/openssl-probe/RUSTSEC-0000-0000.md b/crates/openssl-probe/RUSTSEC-0000-0000.md new file mode 100644 index 000000000..2bb7f214f --- /dev/null +++ b/crates/openssl-probe/RUSTSEC-0000-0000.md @@ -0,0 +1,83 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "openssl-probe" +date = "2025-01-10" +url = "https://github.com/alexcrichton/openssl-probe/issues/30" +references = ["https://www.edgedb.com/blog/c-stdlib-isn-t-threadsafe-and-even-safe-rust-didn-t-save-us"] +informational = "unsound" +categories = ["memory-corruption"] +cvss = "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H" +keywords = ["ssl", "openssl", "environment"] + +[affected.functions] +"openssl_probe::try_init_ssl_cert_env_vars" = ["< 0.1.6"] +"openssl_probe::init_ssl_cert_env_vars" = ["< 0.1.6"] + +[affected] +os = ["linux"] + +[versions] +patched = [">= 0.1.6"] +``` + +# `openssl-probe` may cause memory corruption in multi-threaded processes + +`openssl-probe` offers non-`unsafe` methods that call `std::env::set_var`, which may be called +in a multithreaded environment, and potentially clash with environment access on other threads. +In pure Rust code, concurrent read and write access to the environment is actually safe due to a lock +taken in the platform implementations of the environment accessors (the documentation does not +state this, and it's possible it _could_ change in the future). Libraries using other runtimes +(including Python, those written in pure C and others) do not make use of these internal Rust +environment locks, however, and instead use their own locks, or unprotected raw access to `libc`'s +`getenv`, `setenv`, or even worse, `char** environ`. + +When these methods in `openssl-probe` (or that matter, any other pure Rust code calling `std::env::set_env`) +are called while other threads are active and accessing the environment, it +may cause other threads to access dangling environment pointers in the cases where the underlying +environment data is moved or resized in response to an additional environment variable being +added, or a variable's contents being enlarged. + +This is shown to occur on Linux, but it will also likely occur on any other platform where `getenv` +and `setenv` are not thread-safe, though trigger conditions may vary widely. + +Note that these function calls are completely safe and sound in purely single-threaded environments, +or multi-threaded environments where it can be proven that no simultaneous read and writes to the +environment occur. + +## Rust's `set_env` + +This crate, and all other callers of the Rust `set_env` function () +are unsound due to the unfortunate reality of the POSIX standard which defines these environment access methods +without making any sort of thread-safety guarantees. + +In Rust's 2024 edition `std::env::set_var` is marked as `unsafe` and the documentation was updated to note +that the only safe way to use these functions is in a single-threaded context. + +## Affected Code + +The affected functions are `init_ssl_cert_env_vars` and `try_init_ssl_cert_env_vars` in + and , respectively, and +any other crate's call-graph which may call this function directly or indirectly +<[https://github.com/search?q=try_init_ssl_cert_env_vars&type=code](https://github.com/search?q=try_init_ssl_cert_env_vars+OR+init_ssl_cert_env_vars&type=code)>. `native_tls <= 0.2.12` may +do so in certain configurations . + +## Fix and Mitigation + +The crate's author released a fix in versions `>=0.1.6` which marks these functions as `#[deprecated]` and adds +new `unsafe` equivalents with safety guidance . + +The correct fix is to use the safe `openssl_probe::probe` method to fetch the certificate location, and pass that to +[the new `load_verify_locations` method](https://docs.rs/openssl/latest/openssl/ssl/struct.SslConnectorBuilder.html#method.load_verify_locations) available in `openssl` >= 0.10.69: + + - https://github.com/neonmoe/minreq/commit/4bc16dba61ae19e3f81de33b80c8a3c0c8a33a0d + - https://github.com/sfackler/rust-native-tls/commit/a35127a5cc6d0519c4d6b4dce1fb14ab945ad347 + +### Alternative Mitigations + +In the case of glibc users, some future thread-safety improvements may protect you from `setenv`/`getenv` clashes +which were introduced in , +however direct `environ` access in multithreaded programs will still risk dangling pointer access. + +Users of other `libc` implementations should consult their sourcecode listings for thread-safety guarantees +around multithreaded environment read/write access, though readers should be prepared to be disappointed.