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

Tracking Issue for Rust 2024: Make std::env::{set_var, remove_var} unsafe #124866

Closed
4 of 5 tasks
traviscross opened this issue May 7, 2024 · 19 comments
Closed
4 of 5 tasks
Assignees
Labels
A-edition-2024 Area: The 2024 edition C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. S-tracking-ready-for-edition Status: This issue is ready for inclusion in the edition. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@traviscross
Copy link
Contributor

traviscross commented May 7, 2024

This is a tracking issue for making std::env::{set_var, remove_var} unsafe to call in Rust 2024.

About tracking issues

Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

TODO.

Related

Implementation history

cc @tbu @Amanieu @rust-lang/libs-api

@traviscross traviscross added C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. A-edition-2024 Area: The 2024 edition labels May 7, 2024
@traviscross
Copy link
Contributor Author

@rustbot assign @tbu

@rustbot rustbot self-assigned this May 7, 2024
@traviscross traviscross added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label May 7, 2024
@joboet
Copy link
Contributor

joboet commented May 9, 2024

I'm really not a big fan of this, because unsafe is completely unnecessary on well-behaved platforms like Windows, which provide a good API with proper synchronization, and on the platforms where this is an issue, we could easily make the API sound by properly enforcing that setenv is only called on the main thread (our current behaviour is technically unspecified, see MT-safe env). (not correct) it adds a very subtle safety condition that is almost impossible to reliable satisfy (quite some C library function access the environment internally and you'd have to guarantee that none of them is currently running).

I think the best solution would be to contribute new API to glibc/musl... that behaves correctly (e.g. by copying the GetEnvironmentVariable behaviour of copying into a user-provided buffer).

@BurntSushi
Copy link
Member

@joboet The nooks and crannies of this issue have been discussed at length already. Your suggestion to "add a new API" to glibc/musl has been brought up before and it isn't viable. I would suggest at least skimming through that thread, and pay special attention to richfelker's comments if you think the solution to this problem can come from libc. (He is the maintainer of musl.)

I'm really not a big fan of this, because unsafe is completely unnecessary on well-behaved platforms like Windows, which provide a good API with proper synchronization

I don't think anyone is a big fan of this. The fact that Windows has a safe API for this isn't sufficient criteria for marking a platform independent API safe that is unsafe on some set of supported tier1 platforms. The answer here is to probably to publish a crate that exposes the safe Windows specific API.

@RalfJung
Copy link
Member

RalfJung commented May 9, 2024

I think the best solution would be to contribute new API to glibc/musl... that behaves correctly (e.g. by copying the GetEnvironmentVariable behaviour of copying into a user-provided buffer).

I agree. I hope someone will pursue this.

However, there was, as far as I can tell, basically zero progress on this in the almost 9 years (!) since #27970 was filed. I see no reason to believe that a fix for this will materialize medium-term (let's say, ≤ 5 years). Even on a 10-year scale I am not optimistic that anything will happen. Saying we have to wait until Linux and macOS get their APIs fixed is, at this point, basically equivalent to saying we're okay with this just not being fixed, and std being perpetually unsound when programs combine Rust code and C code.

Given that the best solution is just unrealistic, we should pursue the second-best solution, and that's what we are doing right now. I'm very happy to finally see progress on this.

it adds a very subtle safety condition that is almost impossible to reliable satisfy (quite some C library function access the environment internally and you'd have to guarantee that none of them is currently running).

The safety constraint is basically, don't mutate the environment if another thread may exist. That's the only way we can be sure there's no concurrently running C code. This is sad, but two of our Tier 1 OSes do not support anything better than that, and we can either accept or deny this fact but it remains a fact.

This hopefully pushes the Rust ecosystem towards APIs that avoid the need for mutating the environment.

tbu- added a commit to tbu-/rust that referenced this issue May 13, 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
tbu- added a commit to tbu-/rust that referenced this issue May 13, 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
@traviscross traviscross added S-tracking-impl-incomplete Status: The implementation is incomplete. S-tracking-needs-migration-lint Status: This item needs a migration lint. S-tracking-needs-documentation Status: Needs documentation. labels May 21, 2024
tbu- added a commit to tbu-/rust that referenced this issue May 24, 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
tbu- added a commit to tbu-/rust that referenced this issue May 24, 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
@tbu-
Copy link
Contributor

tbu- commented May 28, 2024

@rustbot claim

@rustbot rustbot assigned tbu- and unassigned rustbot May 28, 2024
@traviscross traviscross removed the S-tracking-needs-migration-lint Status: This item needs a migration lint. label May 28, 2024
tbu- added a commit to tbu-/rust that referenced this issue May 29, 2024
Allow calling these functions without `unsafe` blocks in editions up
until 2021, but don't trigger the `unused_unsafe` lint for `unsafe`
blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
fmease added a commit to fmease/rust that referenced this issue May 30, 2024
Make `std::env::{set_var, remove_var}` unsafe in edition 2024

Allow calling these functions without `unsafe` blocks in editions up until 2021, but don't trigger the `unused_unsafe` lint for `unsafe` blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
bors added a commit to rust-lang-ci/rust that referenced this issue May 30, 2024
Make `std::env::{set_var, remove_var}` unsafe in edition 2024

Allow calling these functions without `unsafe` blocks in editions up until 2021, but don't trigger the `unused_unsafe` lint for `unsafe` blocks containing these functions.

Fixes rust-lang#27970.
Fixes rust-lang#90308.
CC rust-lang#124866.
@ehuss
Copy link
Contributor

ehuss commented May 31, 2024

It's a bit unclear to me why the migration lint was named deprecated_safe, since it is specific to the 2024 edition. @tbu- Would it be possible to rename it to something more specific for its purpose? Perhaps something like deprecated_safe_2024 to mirror keyword_idents_20241?

Footnotes

  1. Unfortunately it looks like there is inconsistency in the naming conventions, with most lints using rust-2021-xxxx but keyword idents split into keyword-idents-20xx. I'm guessing deprecated_safe might follow in similar footsteps. 🤷

@SteveLauC
Copy link
Contributor

Hi, is this considered a breaking change? The patch for this is available in Rust nightly 1.80 2024-05-31, and Nix encountered this even though we are using Rust 2021.

@ehuss
Copy link
Contributor

ehuss commented Jun 2, 2024

@SteveLauC This should only fire in 2024. If you are encountering a problem, please open a new issue with a reproduction.

@SteveLauC
Copy link
Contributor

@SteveLauC This should only fire in 2024. If you are encountering a problem, please open a new issue with a reproduction.

Hi, thanks for your reply! issue filed.

@tbu-
Copy link
Contributor

tbu- commented Jun 3, 2024

Would it be possible to rename it to something more specific for its purpose? Perhaps something like deprecated_safe_2024 to mirror keyword_idents_2024?

Of course it's possible to rename the lint, if we want to do that.

It's a bit unclear to me why the migration lint was named deprecated_safe, since it is specific to the 2024 edition.

My thinking was that the deprecated_safe mechanism might be properly extended to more editions or third-party crates in the future and didn't want to give it a too specific name. I guess a deprecated_safe lint group could be added containing only the deprecated_safe_2024 lint, but I was thinking that this could also be done in the future, when we split it into multiple different lints.

@workingjubilee
Copy link
Member

Why can the behavior of a lint not change? I didn't think this was part of our stability guarantees.

It is explicitly not.

@workingjubilee
Copy link
Member

workingjubilee commented Jun 4, 2024

RFC 1122 Underspecified language semantics:

There are a number of areas where the precise language semantics are currently somewhat underspecified. Over time, we expect to be fully defining the semantics of all of these areas. This may cause some existing code – and in particular existing unsafe code – to break or become invalid. Changes of this nature should be treated as soundness changes, meaning that we should attempt to mitigate the impact and ease the transition wherever possible.

Known areas where change is expected include the following:

For those who don't have time to reread the entire RFC, all soundness changes are considered permitted breaking changes, especially including

  • Cases where the user is able to produce Undefined Behavior (UB) purely from safe code.

It is a permitted breaking change to simply delete these functions. It is recommended by the same RFC to introduce mitigations so that the breakage is minimized. This change is thus effectively one of the recommended mitigation strategies. As it is a lint, its behavior itself is allowed to evolve going forward.

@ehuss
Copy link
Contributor

ehuss commented Jun 5, 2024

Why can the behavior of a lint not change?

In this particular case, it's because the set of unsafe functions that need to be migrated for 2024 will be fixed once 2024 is stabilized. The lint machinery itself does not support a single lint spanning multiple editions (and that is the reason why keyword_idents was split up), so deprecated_safe would not be able to add new functions that would otherwise hard-error, even for 2027.

As for @workingjubilee's context about fixing soundness, there is some latitude to make fixes regarding soundness, but in this case it was decided to fix it in a non-breaking manner. (Unless I'm misunderstanding the point being drawn?)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 5, 2024
…safe_fn, r=Nadrieril

Don't trigger `unsafe_op_in_unsafe_fn` for deprecated safe fns

Fixes rust-lang#125875.

Tracking:

- rust-lang#124866
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 6, 2024
…safe_fn, r=Nadrieril

Don't trigger `unsafe_op_in_unsafe_fn` for deprecated safe fns

Fixes rust-lang#125875.

Tracking:

- rust-lang#124866
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jun 6, 2024
Rollup merge of rust-lang#125925 - tbu-:pr_unsafe_env_unsafe_op_in_unsafe_fn, r=Nadrieril

Don't trigger `unsafe_op_in_unsafe_fn` for deprecated safe fns

Fixes rust-lang#125875.

Tracking:

- rust-lang#124866
@ehuss
Copy link
Contributor

ehuss commented Jun 7, 2024

Posted a draft of the docs at rust-lang/edition-guide#304 if anyone wants to help review that.

compiler-errors added a commit to compiler-errors/rust that referenced this issue Jun 12, 2024
Add TODO comment to unsafe env modification

Addresses rust-lang#124636 (comment).

I think that the diff display regresses a little, because it's no longer showing the `+` to show where the `unsafe {}` is added. I think it's still fine.

Tracking:
- rust-lang#124866

r? `@RalfJung`
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jun 12, 2024
Rollup merge of rust-lang#126019 - tbu-:pr_unsafe_env_fixme, r=fee1-dead

Add TODO comment to unsafe env modification

Addresses rust-lang#124636 (comment).

I think that the diff display regresses a little, because it's no longer showing the `+` to show where the `unsafe {}` is added. I think it's still fine.

Tracking:
- rust-lang#124866

r? `@RalfJung`
tbu- added a commit to tbu-/rust that referenced this issue Jul 17, 2024
Create a lint group `deprecated_safe` that includes
`deprecated_safe_2024`.

Addresses rust-lang#124866 (comment).
tgross35 added a commit to tgross35/rust that referenced this issue Jul 22, 2024
Rename `deprecated_safe` lint to `deprecated_safe_2024`

Create a lint group `deprecated_safe` that includes `deprecated_safe_2024`.

Addresses rust-lang#124866 (comment).

r? `@ehuss`
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jul 22, 2024
Rollup merge of rust-lang#125990 - tbu-:pr_unsafe_env_lint_name, r=ehuss

Rename `deprecated_safe` lint to `deprecated_safe_2024`

Create a lint group `deprecated_safe` that includes `deprecated_safe_2024`.

Addresses rust-lang#124866 (comment).

r? `@ehuss`
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Aug 13, 2024
…trochenkov

Allow to customize `// TODO:` comment for deprecated safe autofix

Relevant for the deprecation of `CommandExt::before_exit` in rust-lang#125970.

Tracking:
- rust-lang#124866
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Aug 13, 2024
…trochenkov

Allow to customize `// TODO:` comment for deprecated safe autofix

Relevant for the deprecation of `CommandExt::before_exit` in rust-lang#125970.

Tracking:
- rust-lang#124866
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Aug 14, 2024
Rollup merge of rust-lang#127857 - tbu-:pr_deprecated_safe_todo, r=petrochenkov

Allow to customize `// TODO:` comment for deprecated safe autofix

Relevant for the deprecation of `CommandExt::before_exit` in rust-lang#125970.

Tracking:
- rust-lang#124866
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Aug 14, 2024
CommandExt::before_exec: deprecate safety in edition 2024

Similar to `set_var`, we had to find out after 1.0 was released that `before_exec` should have been unsafe. We partially rectified this by deprecating that function a long time ago, but since rust-lang#124636 we have the ability to also deprecate the safety of the old function and make it a *hard error* to call the old function outside `unsafe` in the next edition. So just in case anyone still uses the old function, let's ensure this can't be ignored when moving code to the new edition.

Cc `@rust-lang/libs-api`

Tracking:

- rust-lang#124866
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Aug 15, 2024
Rollup merge of rust-lang#125970 - RalfJung:before_exec, r=m-ou-se

CommandExt::before_exec: deprecate safety in edition 2024

Similar to `set_var`, we had to find out after 1.0 was released that `before_exec` should have been unsafe. We partially rectified this by deprecating that function a long time ago, but since rust-lang#124636 we have the ability to also deprecate the safety of the old function and make it a *hard error* to call the old function outside `unsafe` in the next edition. So just in case anyone still uses the old function, let's ensure this can't be ignored when moving code to the new edition.

Cc `@rust-lang/libs-api`

Tracking:

- rust-lang#124866
@ehuss ehuss removed S-tracking-impl-incomplete Status: The implementation is incomplete. S-tracking-needs-documentation Status: Needs documentation. labels Aug 15, 2024
@traviscross
Copy link
Contributor Author

@rustbot labels +S-tracking-ready-for-edition

We reviewed this in our edition call today. This item is ready for Rust 2024.

Thanks to @tbu- and @RalfJung for pushing forward this important work. And thanks to the many reviewers for providing helpful feedback.

@rustbot rustbot added the S-tracking-ready-for-edition Status: This issue is ready for inclusion in the edition. label Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-edition-2024 Area: The 2024 edition C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. S-tracking-ready-for-edition Status: This issue is ready for inclusion in the edition. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants