diff options
| author | ilikepugs <[email protected]> | 2026-07-18 12:52:18 +0300 |
|---|---|---|
| committer | ilikepugs <[email protected]> | 2026-07-18 14:20:59 +0300 |
| commit | 94a1a2d91ceb33eed9e90ccf64804ce0d965dd33 (patch) | |
| tree | 3e91f30dcedc7eb3bf0488620513413a3961f99b | |
| parent | b380fb10c455ef444598f351b828e2764632d1fc (diff) | |
Fix environment pointer invalidation in TShellCommand
TShellCommand built the environment array by storing pointers to strings while simultaneously appending those strings to a vector.
When the vector reallocated, short strings using SSO were moved together with their inline storage. Previously stored pointers could therefore become dangling and cause environment variables passed to the child process to be corrupted or lost.
Build all environment strings first and only then create the pointer array passed to execve. This ensures that the underlying string storage remains stable for the lifetime of the pointer array.
commit_hash:039e0f4a94f1eedea47e53e1258b36a7266193df
| -rw-r--r-- | util/system/shellcommand.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/util/system/shellcommand.cpp b/util/system/shellcommand.cpp index 4853b357cf5..48c1717b7e6 100644 --- a/util/system/shellcommand.cpp +++ b/util/system/shellcommand.cpp @@ -780,11 +780,16 @@ void TShellCommand::TImpl::Run() { qargv.push_back(nullptr); TVector<TString> envHolder; + envHolder.reserve(Options_.Environment.size()); + for (const auto& [name, value] : Options_.Environment) { + envHolder.emplace_back(name + '=' + value); + } + TVector<char*> envp; - if (!Options_.Environment.empty()) { - for (auto& env : Options_.Environment) { - envHolder.emplace_back(env.first + '=' + env.second); - envp.push_back(const_cast<char*>(envHolder.back().data())); + if (!envHolder.empty()) { + envp.reserve(envHolder.size() + 1); + for (auto& env : envHolder) { + envp.push_back(const_cast<char*>(env.data())); } envp.push_back(nullptr); } |
