-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fixes #55775 -- fixed regression in Command::exec's handling of PATH. #55793
Conversation
Thanks for this! To confirm, it sounded like you took a look at glibc's source to start off with, is this what glibc actually does in terms of its exec method? |
Not really, it just calls Which, under the original code, would be the new env we just built. To be honest, I don't fully understand why this behavior occurs. |
Oh I think this is the operative line of code where if That's... really weird. Let's discuss this a bit more on the issue |
Ooof, you're right. I think I should change this patch to match that behavior. Do you agree? |
Ok yeah I think it's probably best to basically continue to match glibc in this regard, so let's have the fallback of a missing I think we perhaps later may want to seriously look into what it would take to change up |
fc185df
to
1a1b53e
Compare
Done. If nothing else we're getting some more tests for |
Heh, indeed! |
1a1b53e
to
893f539
Compare
This should be good to go. |
@bors: r+ |
📌 Commit 893f539 has been approved by |
…r=alexcrichton Fixes rust-lang#55775 -- fixed regression in Command::exec's handling of PATH. This restores the previous behavior where if env_clear() or env_remove() was used, the parent's PATH would be consulted. r? @alexcrichton
@bors r- The new tests likely failed on |
Does android not have |
@alex iirc android doesn't have |
It has |
Ooof, thanks. |
893f539
to
cda8d6a
Compare
Added an Android specific fallback path. |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
musl uses a different set of paths again: https://git.musl-libc.org/cgit/musl/tree/src/process/execvp.c#n21 Every libc seems to differ so If we're going to hardcode these paths we'll have to check every libc. |
cda8d6a
to
a17d79e
Compare
… of PATH. This restores the previous behavior where if env_clear() or env_remove("PATH") was used we fall back to a default PATH of "/bin:/usr/bin"
a17d79e
to
7226f41
Compare
Are there other libc's I ought to check? (It's worth noting that for some of these, the fallback-path varies based on compilation options. I selected the one I understand to be the standard choice.) |
Before we go too much further down this path, perhaps we should take a step back and see if this is the right approach? The original PR was fixing #46775 which is largely just working with It seems to me like a simpler solution for #55775 (the regression here) is to revert #55359 and simply access @alex does that fix sound right to you? |
I don't agree with this analysis. a) I don't believe there's any cases where we're reading from the global env without a lock. In this patch we access the temporary env directly, which is fine because we own it, and we access the process env via the public std APIs, which are safe. b) Adding a lock would not fix the issue I described in #46775 where we have a global reference that escapes the lifetime of the value it points at. It's possible there's a different approach than the one I took that'd work, but I don't believe additional locking is necessary or sufficient. |
Hm isn't this line reading the environment without a lock? (at least in some situations) For adding a lock, I'm thinking the code looks like this: let _guard = acquire_env_lock();
let old_env = *sys::os::environ();
*sys::os::environ() = new_env;
let _reset_on_drop = on_drop(|| { *sys::os::environ() = old_env; });
// do the exec We only temporarily change the entire environment for the block, but outside the block no other thread will see a visible change |
Hmm, accessing Your actual proposal isn't about the locking (though it's necessary for safety), it's about changing the code back to mutating the env, so we can just let libc do it's thing, and ensuring we restore the pointer if we fail. Is that right? |
Heh sure yeah! That's a good way to put it too. Basically we take the original code and update it to restore the old env on failure. That would fix your test cases I believe (because the env doesn't change across calls to Aftewards we'd then fix the orthogonal issue of "what if other threads are running around during |
Yes, I think that'd work. I won't have time to work on it for another few days (probably the weekend). If anyone else is rearing to work on this, you're welcome to steal it, otherwise I"ll get to this then. |
This restores the previous behavior where if env_clear() or env_remove() was used, the parent's PATH would be consulted.
r? @alexcrichton