Prevent mutating the global environment pointer in CommandExt::exec and opt to use execve and resolve path manually#157144
Conversation
…nd opt to use execve and resolve path manually
|
r? @joboet rustbot has assigned @joboet. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
I highly recommend having a look at the POSIX specification – GNU/Linux mostly follows that, but the specification sometimes leaves some things unspecified and we should be careful not to break those.
Also, this is currently unsound, we cannot perform any memory allocation in do_exec, since it's called after fork for the standard spawn path. You probably need to preallocate some memory when creating the Command (or when setting certain parameters).
| None => c"/bin:/usr/bin".to_bytes_with_nul(), | ||
| } | ||
| } | ||
| None => parent_path.as_bytes_with_nul(), |
There was a problem hiding this comment.
I recommend moving the environment variable lookup here so that it's only performed when actually needed.
|
Reminder, once the PR becomes ready for a review, use |
…confstr_as_cstring added to get a CString value returned by confstr, added CStringArray::from_ptr, added default_path and shell_argv fields to unix Command, and refactored do_exec code
This comment has been minimized.
This comment has been minimized.
…om a single passthrough in envp, match on errno values directly instead of ErrorKind, fix shell_argv CStringArray value.
213bb02 to
8319b09
Compare
This comment has been minimized.
This comment has been minimized.
| assert_failed(index, len); | ||
| } | ||
|
|
||
| self.ptrs.insert(index, item.into_raw()); |
There was a problem hiding this comment.
This leaks the string if insert panics (see #155748, I made this mistake before).
46fcd5d to
d818868
Compare
d818868 to
22776c7
Compare
22776c7 to
df73301
Compare
…remove confstr_as_cstr, remove unnecessary shell_argv field/funtions + unused functions from CStringArray, use slice::split to delimit on colons
df73301 to
0ecb419
Compare
e3d0663 to
9851b0a
Compare
9851b0a to
b4723b8
Compare
…cumentation for returning an error from execve
b4723b8 to
df00000
Compare
View all comments
This PR fixes the bug described in #156951 where
CommandExt::execmutating the global environment pointer could cause correctness issue with concurrentexeccalls (also this function holds an environment read lock, so it shouldn't cause any writes to the global environment pointer anyways). We do everything withinCommandExt::execviaexecvethanexecvp, which means we have to resolve the path manually.I took reference to what was done in an archived (Feb 2026) upstream mirror of glibc's
execvpandexecvpe. I also took reference to #55359 on how they implemented the concerned portion ofCommandExt::execwithexecve. There's also this OpenBSD libc implementation ofexecvpethat I saw, but I didn't deeply take a look at this one and saw how it differ.Other than that, I'm unsure how to handle the error
ETIMEOUT/TimedOutas glibc breaks parsing through thePATHenvironment variable value and returns the error while #55359 continues parsing.Let me know if you also want me to put some of
execvecode in a helper function or refactor it in other ways.