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

Fix rustc sysroot in systems using CAS #79253

Merged
merged 1 commit into from
Feb 6, 2021
Merged

Fix rustc sysroot in systems using CAS #79253

merged 1 commit into from
Feb 6, 2021

Conversation

rcvalle
Copy link
Member

@rcvalle rcvalle commented Nov 21, 2020

Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 21, 2020
@jyn514
Copy link
Member

jyn514 commented Nov 21, 2020

r? @Mark-Simulacrum

@jyn514 jyn514 added the T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) label Nov 21, 2020
@jyn514
Copy link
Member

jyn514 commented Nov 21, 2020

@rcvalle what is content-addressable storage? Do you mean like a nix store or something?

@Mark-Simulacrum
Copy link
Member

I don't think I can effectively review this patch without more information -- switching away from current_exe feels like the wrong approach though. If it was a "true" content-addressable storage system I would expect paths to be largely meaningless, so the popping that is still present wouldn't work really either...?

@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 22, 2020
@rcvalle
Copy link
Member Author

rcvalle commented Nov 24, 2020

@rcvalle what is content-addressable storage? Do you mean like a nix store or something?

Content-addressable storage (CAS) is a method of storing information so it can be retrieved based on its content (usually using a hashing function appropriate for CAS) instead of its location. (Git itself is an userspace CAS filesystem.)

@rcvalle
Copy link
Member Author

rcvalle commented Nov 24, 2020

I don't think I can effectively review this patch without more information -- switching away from current_exe feels like the wrong approach though. If it was a "true" content-addressable storage system I would expect paths to be largely meaningless, so the popping that is still present wouldn't work really either...?

Sorry, I should have provided more information. We use CAS in our build systems with symlink forests to replicate the locations files originally belong. However, since both env::current_exe() and fs::canonicalize() follow symlinks/canonicalize the components of the path, the symlinks were being followed to the CAS locations, making the rustc binary unable to locate its distributed libraries.

@Mark-Simulacrum
Copy link
Member

Mark-Simulacrum commented Nov 24, 2020

Hm, ok. I'm not sure I'm willing to land this change -- it seems like there are cases where that canonicalization would be necessary. Generally the sysroot discovery is a bit ad-hoc in rustc and not super well polished. I think my suggestion would be that we try both - it looks like perhaps the sysroot_candidates function can be extended to also visit the non-canonicalized path. I'm not actually quite sure why we don't use that function to discover the sysroot in librustc_session (cc @bjorn3 since you modified the sysroot code recently), but instead just call the current_exe-based function.

@bjorn3
Copy link
Member

bjorn3 commented Nov 24, 2020

If I run rustc a.rs, env::args().next() would return rustc, right? In that case it will look for the sysroot in ../, which is unlikely to be the real sysroot location.

However, since it can be set to an arbitrary value, fs::get_or_default_sysroot() and its return value should not be relied on for security-related decisions.

Rustc runs with the same permissions as the user. I personally don't see how security is relevant here. It can only be invoked by the user. Also the sysroot is most of the time only used to load the files the crate will link against. Only with -Zcodegen-backend can it dynamically link against a dylib in the sysroot.

@bjorn3
Copy link
Member

bjorn3 commented Nov 24, 2020

sysroot_candidates calls get_or_default_sysroot. The former also searches relative to the rustc_driver dylib for custom drivers, while the later only searches relative to the main executable. sysroot_candidates was necessary when cg_llvm was a hotpluggable codegen backend. Otherwise custom drivers wouldn't find the llvm codegen backend.

@rcvalle
Copy link
Member Author

rcvalle commented Dec 1, 2020

If I run rustc a.rs, env::args().next() would return rustc, right? In that case it will look for the sysroot in ../, which is unlikely to be the real sysroot location.

Indeed. We could perhaps check if sysroot is found using env::args().next(), and if it's not found, use env::current_exe(). What do you think?

However, since it can be set to an arbitrary value, fs::get_or_default_sysroot() and its return value should not be relied on for security-related decisions.

Rustc runs with the same permissions as the user. I personally don't see how security is relevant here. It can only be invoked by the user. Also the sysroot is most of the time only used to load the files the crate will link against. Only with -Zcodegen-backend can it dynamically link against a dylib in the sysroot.

It may be relevant in a multiuser or remote system, where the rustc binary may be executed by a different user with different privileges.

@rcvalle
Copy link
Member Author

rcvalle commented Dec 11, 2020

@bjorn3 @Mark-Simulacrum I've amended my commit to check if sysroot is found using env::args().next(), and if it's not found, use env::current_exe() instead. What do you think?

@rcvalle
Copy link
Member Author

rcvalle commented Dec 16, 2020

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@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 Dec 16, 2020
// This makes the rustc binary able to locate Rust libraries in systems
// using content-addressable storage (CAS). However, since it can be set to
// an arbitrary value, fs::get_or_default_sysroot() and its return value
// should not be relied on for security-related decisions.
Copy link
Member

Choose a reason for hiding this comment

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

This last sentence seems misleading, as it applies just as much to from_current_exe. I would perhaps expect to see it on the get_or_default_sysroot function itself.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. (I improved the changes a bit and fixed the comments.)

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 23, 2020
@Mark-Simulacrum
Copy link
Member

I am still concerned about this change. It seems like it could easily lead to confusion if there are (by accident or intentionally) different sysroots at argv0 and current_exe. That said, it does seem like the problem you're running into is a real one - I just am not sure this is the right solution. Can you say more about how other compilers or programs that need more than one file deal with this in your system? I think overall I just don't have enough expertise to weigh in here. cc @rust-lang/compiler - maybe someone can chime in if they have experience or thoughts here.

@wesleywiser
Copy link
Member

Perhaps we should consider adding a flag that would allow specifying the sysroot path instead?

@jyn514
Copy link
Member

jyn514 commented Dec 24, 2020

@wesleywiser there's already a --sysroot flag:

$ rustc --help -v | grep sysroot
        --print [crate-name|file-names|sysroot|target-libdir|cfg|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|native-static-libs]
        --sysroot PATH  Override the system root

@wesleywiser
Copy link
Member

Thanks @jyn514! GitHub hid this comment which has the motivation for the change.

@bors
Copy link
Contributor

bors commented Jan 31, 2021

⌛ Testing commit 3f679fe with merge 9a61ec508e22d4488fa01c424e3bd85bb7d02027...

@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Jan 31, 2021

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jan 31, 2021
@rcvalle
Copy link
Member Author

rcvalle commented Feb 3, 2021

Thank you @nagisa, @Mark-Simulacrum, @jyn514, @bjorn3, and others for your time on this! Much appreciated.

@rcvalle
Copy link
Member Author

rcvalle commented Feb 3, 2021

@bors retry

@bors
Copy link
Contributor

bors commented Feb 3, 2021

@rcvalle: 🔑 Insufficient privileges: not in try users

@jyn514
Copy link
Member

jyn514 commented Feb 3, 2021

@bors retry

@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 Feb 3, 2021
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 3, 2021
…gisa

Fix rustc sysroot in systems using CAS

Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Feb 3, 2021
…gisa

Fix rustc sysroot in systems using CAS

Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 4, 2021
…gisa

Fix rustc sysroot in systems using CAS

Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
m-ou-se added a commit to m-ou-se/rust that referenced this pull request Feb 4, 2021
…gisa

Fix rustc sysroot in systems using CAS

Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
@bors
Copy link
Contributor

bors commented Feb 5, 2021

⌛ Testing commit 3f679fe with merge 16b8057...

@bors
Copy link
Contributor

bors commented Feb 6, 2021

☀️ Test successful - checks-actions
Approved by: nagisa
Pushing 16b8057 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Feb 6, 2021
@bors bors merged commit 16b8057 into rust-lang:master Feb 6, 2021
@rustbot rustbot added this to the 1.51.0 milestone Feb 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.