Skip to content

Commit

Permalink
Add discussion that concurrent access to the environment is unsafe
Browse files Browse the repository at this point in the history
The bug report rust-lang#27970 has existed for 8 years, the actual bug dates back
to Rust pre-1.0. I documented it since it's in the interest of the user
to be aware of it. The note can be removed once rust-lang#27970 is fixed.
  • Loading branch information
tbu- committed Oct 18, 2023
1 parent e8b8c78 commit 8057586
Showing 1 changed file with 28 additions and 10 deletions.
38 changes: 28 additions & 10 deletions library/std/src/env.rs
Expand Up @@ -313,17 +313,26 @@ impl Error for VarError {
/// Sets the environment variable `key` to the value `value` for the currently running
/// process.
///
/// Note that while concurrent access to environment variables is safe in Rust,
/// some platforms only expose inherently unsafe non-threadsafe APIs for
/// inspecting the environment. As a result, extra care needs to be taken when
/// auditing calls to unsafe external FFI functions to ensure that any external
/// environment accesses are properly synchronized with accesses in Rust.
/// Note that while concurrent access to environment variables ought to be safe
/// in Rust, some platforms only expose inherently unsafe non-threadsafe APIs
/// for inspecting the environment. As a result, using `set_var` or
/// `remove_var` in a multi-threaded Rust program can lead to undefined
/// behavior, for example in combination with DNS lookups from
/// [`std::net::ToSocketAddrs`]. This is a bug
/// ([rust#27970](https://github.com/rust-lang/rust/issues/27970)) and will be
/// fixed in a future version of Rust. Additionally, extra care needs to be
/// taken when auditing calls to unsafe external FFI functions to ensure that
/// any external environment accesses are properly synchronized with accesses
/// in Rust. Since Rust does not expose its environment lock directly, this
/// means that all accesses to the environment must go through Rust's [`var`].
///
/// Discussion of this unsafety on Unix may be found in:
///
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
///
/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
Expand Down Expand Up @@ -351,17 +360,26 @@ fn _set_var(key: &OsStr, value: &OsStr) {

/// Removes an environment variable from the environment of the currently running process.
///
/// Note that while concurrent access to environment variables is safe in Rust,
/// some platforms only expose inherently unsafe non-threadsafe APIs for
/// inspecting the environment. As a result extra care needs to be taken when
/// auditing calls to unsafe external FFI functions to ensure that any external
/// environment accesses are properly synchronized with accesses in Rust.
/// Note that while concurrent access to environment variables ought to be safe
/// in Rust, some platforms only expose inherently unsafe non-threadsafe APIs
/// for inspecting the environment. As a result, using `set_var` or
/// `remove_var` in a multi-threaded Rust program can lead to undefined
/// behavior, for example in combination with DNS lookups from
/// [`std::net::ToSocketAddrs`]. This is a bug
/// ([rust#27970](https://github.com/rust-lang/rust/issues/27970)) and will be
/// fixed in a future version of Rust. Additionally, extra care needs to be
/// taken when auditing calls to unsafe external FFI functions to ensure that
/// any external environment accesses are properly synchronized with accesses
/// in Rust. Since Rust does not expose its environment lock directly, this
/// means that all accesses to the environment must go through Rust's [`var`].
///
/// Discussion of this unsafety on Unix may be found in:
///
/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188)
/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2)
///
/// [`std::net::ToSocketAddrs`]: crate::net::ToSocketAddrs
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
Expand Down

0 comments on commit 8057586

Please sign in to comment.