summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorilikepugs <[email protected]>2026-07-18 12:52:18 +0300
committerilikepugs <[email protected]>2026-07-18 14:20:59 +0300
commit94a1a2d91ceb33eed9e90ccf64804ce0d965dd33 (patch)
tree3e91f30dcedc7eb3bf0488620513413a3961f99b
parentb380fb10c455ef444598f351b828e2764632d1fc (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.cpp13
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);
}