12_allow_env_changes.patch (9863B)
1 # HG changeset patch 2 # User Gian-Carlo Pascutto <gcp@mozilla.com> 3 # Date 1515402436 -3600 4 # Mon Jan 08 10:07:16 2018 +0100 5 # Node ID 205e7ae2a6bc5ed1cdd1a982a12d99f52ce33258 6 # Parent a89071894b4904a0130139a03147d4a6cb5c3bfc 7 Bug 1297740. 8 9 diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc 10 --- a/sandbox/win/src/broker_services.cc 11 +++ b/sandbox/win/src/broker_services.cc 12 @@ -414,16 +414,17 @@ DWORD WINAPI BrokerServicesBase::TargetE 13 } 14 return policy; 15 } 16 17 // SpawnTarget does all the interesting sandbox setup and creates the target 18 // process inside the sandbox. 19 ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, 20 const wchar_t* command_line, 21 + base::EnvironmentMap& env_map, 22 std::unique_ptr<TargetPolicy> policy, 23 DWORD* last_error, 24 PROCESS_INFORMATION* target_info) { 25 if (!exe_path) 26 return SBOX_ERROR_BAD_PARAMS; 27 28 // This code should only be called from the exe, ensure that this is always 29 // the case. 30 @@ -609,17 +610,17 @@ ResultCode BrokerServicesBase::SpawnTarg 31 32 // Create the TargetProcess object and spawn the target suspended. Note that 33 // Brokerservices does not own the target object. It is owned by the Policy. 34 base::win::ScopedProcessInformation process_info; 35 std::unique_ptr<TargetProcess> target = std::make_unique<TargetProcess>( 36 std::move(*initial_token), std::move(*lockdown_token), thread_pool_); 37 38 result = target->Create(exe_path, command_line, std::move(startup_info), 39 - &process_info, last_error); 40 + &process_info, env_map, last_error); 41 42 if (result != SBOX_ALL_OK) { 43 target->Terminate(); 44 return result; 45 } 46 47 if (config_base->GetJobLevel() <= JobLevel::kLimitedUser) { 48 // Restrict the job from containing any processes. Job restrictions 49 diff --git a/sandbox/win/src/broker_services.h b/sandbox/win/src/broker_services.h 50 --- a/sandbox/win/src/broker_services.h 51 +++ b/sandbox/win/src/broker_services.h 52 @@ -8,16 +8,17 @@ 53 #include <map> 54 #include <memory> 55 #include <set> 56 #include <string> 57 #include <utility> 58 59 #include "base/compiler_specific.h" 60 #include "base/containers/flat_map.h" 61 +#include "base/environment.h" 62 #include "base/memory/raw_ptr.h" 63 #include "base/memory/scoped_refptr.h" 64 #include "base/win/scoped_handle.h" 65 #include "sandbox/win/src/alternate_desktop.h" 66 #include "sandbox/win/src/crosscall_server.h" 67 #include "sandbox/win/src/sandbox.h" 68 #include "sandbox/win/src/sandbox_policy_base.h" 69 #include "sandbox/win/src/sharedmem_ipc_server.h" 70 @@ -39,16 +40,17 @@ class BrokerServicesBase final : public 71 std::unique_ptr<BrokerServicesTargetTracker> target_tracker) override; 72 ResultCode CreateAlternateDesktop(Desktop desktop) override; 73 void DestroyDesktops() override; 74 std::unique_ptr<TargetPolicy> CreatePolicy() override; 75 std::unique_ptr<TargetPolicy> CreatePolicy(base::StringPiece key) override; 76 77 ResultCode SpawnTarget(const wchar_t* exe_path, 78 const wchar_t* command_line, 79 + base::EnvironmentMap& env_map, 80 std::unique_ptr<TargetPolicy> policy, 81 DWORD* last_error, 82 PROCESS_INFORMATION* target) override; 83 ResultCode GetPolicyDiagnostics( 84 std::unique_ptr<PolicyDiagnosticsReceiver> receiver) override; 85 void SetStartingMitigations(MitigationFlags starting_mitigations) override; 86 bool RatchetDownSecurityMitigations( 87 MitigationFlags additional_flags) override; 88 diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h 89 --- a/sandbox/win/src/sandbox.h 90 +++ b/sandbox/win/src/sandbox.h 91 @@ -84,16 +84,17 @@ class BrokerServices { 92 // parameter will hold the last Win32 error value. 93 // target: returns the resulting target process information such as process 94 // handle and PID just as if CreateProcess() had been called. The caller is 95 // responsible for closing the handles returned in this structure. 96 // Returns: 97 // ALL_OK if successful. All other return values imply failure. 98 virtual ResultCode SpawnTarget(const wchar_t* exe_path, 99 const wchar_t* command_line, 100 + base::EnvironmentMap& env_map, 101 std::unique_ptr<TargetPolicy> policy, 102 DWORD* last_error, 103 PROCESS_INFORMATION* target) = 0; 104 105 // This call creates a snapshot of policies managed by the sandbox and 106 // returns them via a helper class. 107 // Parameters: 108 // receiver: The |PolicyDiagnosticsReceiver| implementation will be 109 diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc 110 --- a/sandbox/win/src/target_process.cc 111 +++ b/sandbox/win/src/target_process.cc 112 @@ -9,16 +9,17 @@ 113 #include <memory> 114 #include <string_view> 115 #include <utility> 116 #include <vector> 117 118 #include "base/containers/span.h" 119 #include "base/memory/free_deleter.h" 120 #include "base/numerics/safe_conversions.h" 121 +#include "base/process/environment_internal.h" 122 #include "base/strings/string_util.h" 123 #include "base/win/access_token.h" 124 #include "base/win/current_module.h" 125 #include "base/win/scoped_handle.h" 126 #include "base/win/security_util.h" 127 #include "base/win/startup_information.h" 128 #include "sandbox/win/src/crosscall_client.h" 129 #include "sandbox/win/src/crosscall_server.h" 130 @@ -137,16 +138,17 @@ TargetProcess::~TargetProcess() { 131 132 // Creates the target (child) process suspended and assigns it to the job 133 // object. 134 ResultCode TargetProcess::Create( 135 const wchar_t* exe_path, 136 const wchar_t* command_line, 137 std::unique_ptr<StartupInformationHelper> startup_info_helper, 138 base::win::ScopedProcessInformation* target_info, 139 + base::EnvironmentMap& env_changes, 140 DWORD* win_error) { 141 exe_name_.reset(_wcsdup(exe_path)); 142 143 base::win::StartupInformation* startup_info = 144 startup_info_helper->GetStartupInformation(); 145 146 // the command line needs to be writable by CreateProcess(). 147 std::unique_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line)); 148 @@ -148,40 +150,48 @@ ResultCode TargetProcess::Create( 149 DWORD flags = 150 CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS; 151 152 if (startup_info->has_extended_startup_info()) 153 flags |= EXTENDED_STARTUPINFO_PRESENT; 154 155 std::wstring new_env; 156 157 + wchar_t* old_environment = ::GetEnvironmentStringsW(); 158 + if (!old_environment) { 159 + return SBOX_ERROR_CANNOT_OBTAIN_ENVIRONMENT; 160 + } 161 + 162 if (startup_info_helper->IsEnvironmentFiltered()) { 163 - wchar_t* old_environment = ::GetEnvironmentStringsW(); 164 - if (!old_environment) { 165 - return SBOX_ERROR_CANNOT_OBTAIN_ENVIRONMENT; 166 - } 167 - 168 // Only copy a limited list of variables to the target from the broker's 169 // environment. These are 170 // * "Path", "SystemDrive", "SystemRoot", "TEMP", "TMP": Needed for normal 171 // operation and tests. 172 // * "LOCALAPPDATA": Needed for App Container processes. 173 // * "CHROME_CRASHPAD_PIPE_NAME": Needed for crashpad. 174 static constexpr base::WStringPiece to_keep[] = { 175 L"Path", 176 L"SystemDrive", 177 L"SystemRoot", 178 L"TEMP", 179 L"TMP", 180 L"LOCALAPPDATA", 181 L"CHROME_CRASHPAD_PIPE_NAME"}; 182 183 new_env = FilterEnvironment(old_environment, to_keep); 184 - ::FreeEnvironmentStringsW(old_environment); 185 + } else { 186 + // Environment strings block is terminated by a double null. 187 + wchar_t* end_ptr = old_environment; 188 + while (*end_ptr++ || *end_ptr++) { 189 + } 190 + new_env.assign(old_environment, end_ptr); 191 } 192 + 193 + ::FreeEnvironmentStringsW(old_environment); 194 + new_env = base::internal::AlterEnvironment(std::data(new_env), env_changes); 195 196 bool inherit_handles = startup_info_helper->ShouldInheritHandles(); 197 PROCESS_INFORMATION temp_process_info = {}; 198 if (!::CreateProcessAsUserW(lockdown_token_.get(), exe_path, cmd_line.get(), 199 nullptr, // No security attribute. 200 nullptr, // No thread attribute. 201 inherit_handles, flags, 202 new_env.empty() ? nullptr : std::data(new_env), 203 diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h 204 --- a/sandbox/win/src/target_process.h 205 +++ b/sandbox/win/src/target_process.h 206 @@ -6,16 +6,17 @@ 207 #define SANDBOX_WIN_SRC_TARGET_PROCESS_H_ 208 209 #include <stddef.h> 210 #include <stdint.h> 211 212 #include <memory> 213 214 #include "base/containers/span.h" 215 +#include "base/environment.h" 216 #include "base/gtest_prod_util.h" 217 #include "base/memory/free_deleter.h" 218 #include "base/memory/raw_ptr.h" 219 #include "base/strings/string_util.h" 220 #include "base/win/access_token.h" 221 #include "base/win/scoped_handle.h" 222 #include "base/win/scoped_process_information.h" 223 #include "base/win/sid.h" 224 @@ -54,16 +55,17 @@ class TargetProcess { 225 226 ~TargetProcess(); 227 228 // Creates the new target process. The process is created suspended. 229 ResultCode Create(const wchar_t* exe_path, 230 const wchar_t* command_line, 231 std::unique_ptr<StartupInformationHelper> startup_info, 232 base::win::ScopedProcessInformation* target_info, 233 + base::EnvironmentMap& env_map, 234 DWORD* win_error); 235 236 // Destroys the target process. 237 void Terminate(); 238 239 // Creates the IPC objects such as the BrokerDispatcher and the 240 // IPC server. The IPC server uses the services of the thread_pool. 241 ResultCode Init(Dispatcher* ipc_dispatcher,