Skip to content

Add discussion that concurrent access to the environment is unsafe #116888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 40 additions & 10 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,32 @@ 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.
/// # Safety
///
/// Even though this function is currently not marked as `unsafe`, it needs to
/// be because invoking it can cause undefined behaviour. The function will be
/// marked `unsafe` in a future version of Rust. This is tracked in
/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
///
/// This function is safe to call in a single-threaded program.
///
/// In multi-threaded programs, you must ensure that are no other threads
/// concurrently writing or *reading*(!) from the environment through functions
/// other than the ones in this module. You are responsible for figuring out
/// how to achieve this, but we strongly suggest not using `set_var` or
/// `remove_var` in multi-threaded programs at all.
///
/// Most C libraries, including libc itself do not advertise which functions
/// read from the environment. Even functions from the Rust standard library do
/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
///
/// 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 +366,32 @@ 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.
/// # Safety
///
/// Even though this function is currently not marked as `unsafe`, it needs to
/// be because invoking it can cause undefined behaviour. The function will be
/// marked `unsafe` in a future version of Rust. This is tracked in
/// [rust#27970](https://github.com/rust-lang/rust/issues/27970).
///
/// This function is safe to call in a single-threaded program.
///
/// In multi-threaded programs, you must ensure that are no other threads
/// concurrently writing or *reading*(!) from the environment through functions
/// other than the ones in this module. You are responsible for figuring out
/// how to achieve this, but we strongly suggest not using `set_var` or
/// `remove_var` in multi-threaded programs at all.
///
/// Most C libraries, including libc itself do not advertise which functions
/// read from the environment. Even functions from the Rust standard library do
/// that, e.g. for DNS lookups from [`std::net::ToSocketAddrs`].
///
/// 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