-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Conversation
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. |
@rcvalle what is content-addressable storage? Do you mean like a |
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...? |
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.) |
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. |
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. |
If I run
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 |
|
Indeed. We could perhaps check if sysroot is found using
It may be relevant in a multiuser or remote system, where the rustc binary may be executed by a different user with different privileges. |
@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? |
@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author |
// 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.)
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. |
Perhaps we should consider adding a flag that would allow specifying the sysroot path instead? |
@wesleywiser there's already a
|
Thanks @jyn514! GitHub hid this comment which has the motivation for the change. |
⌛ Testing commit 3f679fe with merge 9a61ec508e22d4488fa01c424e3bd85bb7d02027... |
💔 Test failed - checks-actions |
Thank you @nagisa, @Mark-Simulacrum, @jyn514, @bjorn3, and others for your time on this! Much appreciated. |
@bors retry |
@rcvalle: 🔑 Insufficient privileges: not in try users |
@bors retry |
…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).
…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).
…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).
…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).
☀️ Test successful - checks-actions |
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).