Skip to content
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

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

Merged
merged 2 commits into from
Dec 15, 2023

Conversation

tbu-
Copy link
Contributor

@tbu- tbu- commented Oct 18, 2023

The bug report #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 #27970 is fixed.

@rustbot
Copy link
Collaborator

rustbot commented Oct 18, 2023

r? @Mark-Simulacrum

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 18, 2023
@rust-log-analyzer

This comment has been minimized.

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.
/// 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes it sound like rust will fix the concurrent access problem, but it cannot. it should say that this function will probably become unsafe in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also seems to me that get_var has the same problems, right? It's reading data that might be changed by concurrent C code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since getenv is usually considered safe in a multithreaded C environment, but setenv/putenv is not, I do not think that it requires an extra note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, C code designed for multithreaded use will almost never write to the env.

/// 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`].
Copy link
Member

@thomcc thomcc Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is requesting something impossible in most cases. I'm not sure that's reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a suggestion what to write there?

Yes, it's unreasonable, but that's the current state of the function AFAICT.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 4, 2023
@tbu-
Copy link
Contributor Author

tbu- commented Nov 23, 2023

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 23, 2023
@tbu-
Copy link
Contributor Author

tbu- commented Nov 23, 2023

@Mark-Simulacrum I don't see any actionable feedback, why is it "waiting-on-author"?

@Mark-Simulacrum
Copy link
Member

fixed in a future version of Rust

I think at minimum we need to remove this implication, this isn't directly fixable in a future version of Rust.

I'm going to also nominate for T-libs-api -- it's not clear to me if the framing here meets our current thinking. In particular,

Note that while concurrent access to environment variables ought to be safe in Rust

My suspicion is that in hindsight these functions should have either not existed or not been safe. i.e., "ought to be safe" isn't accurate here -- usually we do not try to paper over platform unsoundness like this, especially if it's impossible (as is the case here).

@Mark-Simulacrum Mark-Simulacrum added the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Dec 9, 2023
@Mark-Simulacrum
Copy link
Member

(It also seems like this is just extending existing documentation -- i.e., the documentation already calls out this is an underlying unsafe API)

@Amanieu
Copy link
Member

Amanieu commented Dec 12, 2023

We discussed this in the libs-api meeting. What we would like to see happen is that this function gets turned into an unsafe function for the 2024 edition, but on older editions only emits a warning if not inside an unsafe block (possibly using deprecated_safe #94978).

As such the documentation should be written as if this was an unsafe function, clearly explaining the pre-conditions that must be upheld:

  • This function is safe to call in single-threaded programs.
  • In multi-threaded programs, you must ensure that there are no other threads concurrently reading or writing the environment variables while calling this function through APIs other than the standard library (e.g. C code). You are responsible for figuring out how to achieve this, but we strongly suggest not calling set_var in multi-threaded programs at all.

@ChrisDenton
Copy link
Member

In multi-threaded programs, you must ensure that there are no other threads concurrently reading or writing the environment variables while calling this function through APIs other than the standard library (e.g. C code).

It was also brought up that this isn't quite true currently as the rust standard library calls libc functions that may themselves read from the environment. So either those std functions need to be changed to take the environment lock or else we also need to warn against using std functions that may call out to libc.

@tbu-
Copy link
Contributor Author

tbu- commented Dec 13, 2023

As such the documentation should be written as if this was an unsafe function, clearly explaining the pre-conditions that must be upheld: […]

Done.

@Amanieu
Copy link
Member

Amanieu commented Dec 15, 2023

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Dec 15, 2023

📌 Commit 2093d0c has been approved by Amanieu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 15, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 15, 2023
…iaskrgr

Rollup of 3 pull requests

Successful merges:

 - rust-lang#116888 (Add discussion that concurrent access to the environment is unsafe)
 - rust-lang#118888 (Uplift `TypeAndMut` and `ClosureKind` to `rustc_type_ir`)
 - rust-lang#118929 (coverage: Tidy up early parts of the instrumentor pass)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 44fd74a into rust-lang:master Dec 15, 2023
11 checks passed
@rustbot rustbot added this to the 1.76.0 milestone Dec 15, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 15, 2023
Rollup merge of rust-lang#116888 - tbu-:pr_unsafe_env, r=Amanieu

Add discussion that concurrent access to the environment is unsafe

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.
@dtolnay dtolnay removed the I-libs-api-nominated Nominated for discussion during a libs-api team meeting. label Mar 24, 2024
@hkBst
Copy link
Contributor

hkBst commented Jun 13, 2024

The suggested wording seems to imply that it is fine to call the functions in this module in parallel if you don't use any other ways to access the environment, presumably because these functions use some way to synchronize their accesses. It would be great if the text was more explicit about whether this is the case or not.

@tbu-
Copy link
Contributor Author

tbu- commented Jun 13, 2024

The suggested wording seems to imply that it is fine to call the functions in this module in parallel if you don't use any other ways to access the environment, presumably because these functions use some way to synchronize their accesses.

You must also ensure that you don't call any Rust standard library function that reads from the environment (e.g. ToSocketAddrs does). It is not documented which Rust standard library function reads from the environment and can change from version to version.

You must also not call into any C libraries that might read from the environment. Most C libraries do not document whether or in which functions they access the environment, and it can usually also change from version to version.

In that way, you could say that your statement is technically correct. Practically speaking, since you cannot even guarantee what the Rust standard library does, you must only modify the environment variables when you're single-threaded.

It would be great if the text was more explicit about whether this is the case or not.

I agree, and this is why I suggested removing the lock guarantees from the documentation: #125937. IMO unfortunately, this seems to be rejected. You could add a comment there if you think it's an improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.