Commit d611d075 authored by Alex Gough's avatar Alex Gough Committed by Commit Bot

Reduce active process limit to zero in jobs

The active process limit is only checked on process creation so can
safely be dropped to zero. This prevents reuse of the process handle
to launch another process in the job after the contained process has
terminated.

Tested by existing tests.

Bug: 1050359
Change-Id: I803ca74e6a654b46484a945925085e4444a1df07
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2308174Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790622}
parent 4ca3f22c
...@@ -584,6 +584,17 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, ...@@ -584,6 +584,17 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
return result; return result;
} }
if (job.IsValid() && policy_base->GetJobLevel() <= JOB_LIMITED_USER) {
// Restrict the job from containing any processes. Job restrictions
// are only applied at process creation, so the target process is
// unaffected.
result = policy_base->DropActiveProcessLimit(&job);
if (result != SBOX_ALL_OK) {
target->Terminate();
return result;
}
}
if (lowbox_token.IsValid()) { if (lowbox_token.IsValid()) {
*last_warning = target->AssignLowBoxToken(lowbox_token); *last_warning = target->AssignLowBoxToken(lowbox_token);
// If this fails we continue, but report the error as a warning. // If this fails we continue, but report the error as a warning.
......
...@@ -114,4 +114,25 @@ DWORD Job::AssignProcessToJob(HANDLE process_handle) { ...@@ -114,4 +114,25 @@ DWORD Job::AssignProcessToJob(HANDLE process_handle) {
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
// static
DWORD Job::SetActiveProcessLimit(base::win::ScopedHandle* job_handle,
DWORD processes) {
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {};
if (!::QueryInformationJobObject(job_handle->Get(),
JobObjectExtendedLimitInformation, &jeli,
sizeof(jeli), nullptr))
return ::GetLastError();
jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
jeli.BasicLimitInformation.ActiveProcessLimit = processes;
if (!::SetInformationJobObject(job_handle->Get(),
JobObjectExtendedLimitInformation, &jeli,
sizeof(jeli)))
return ::GetLastError();
return ERROR_SUCCESS;
}
} // namespace sandbox } // namespace sandbox
...@@ -54,6 +54,10 @@ class Job { ...@@ -54,6 +54,10 @@ class Job {
// If the object is not yet initialized, it returns an invalid handle. // If the object is not yet initialized, it returns an invalid handle.
base::win::ScopedHandle Take(); base::win::ScopedHandle Take();
// Updates the active process limit for |job_handle|.
static DWORD SetActiveProcessLimit(base::win::ScopedHandle* job_handle,
DWORD processes);
private: private:
// Handle to the job referenced by the object. // Handle to the job referenced by the object.
base::win::ScopedHandle job_handle_; base::win::ScopedHandle job_handle_;
......
...@@ -414,6 +414,16 @@ ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { ...@@ -414,6 +414,16 @@ ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) {
return SBOX_ALL_OK; return SBOX_ALL_OK;
} }
ResultCode PolicyBase::DropActiveProcessLimit(base::win::ScopedHandle* job) {
if (job_level_ >= JOB_INTERACTIVE)
return SBOX_ALL_OK;
if (ERROR_SUCCESS != Job::SetActiveProcessLimit(job, 0))
return SBOX_ERROR_CANNOT_UPDATE_JOB_PROCESS_LIMIT;
return SBOX_ALL_OK;
}
ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial,
base::win::ScopedHandle* lockdown, base::win::ScopedHandle* lockdown,
base::win::ScopedHandle* lowbox) { base::win::ScopedHandle* lowbox) {
......
...@@ -90,6 +90,10 @@ class PolicyBase final : public TargetPolicy { ...@@ -90,6 +90,10 @@ class PolicyBase final : public TargetPolicy {
// SetJobLevel(). // SetJobLevel().
ResultCode MakeJobObject(base::win::ScopedHandle* job); ResultCode MakeJobObject(base::win::ScopedHandle* job);
// Updates the active process limit on the job to zero. Has no effect
// if the job is allowed to spawn processes.
ResultCode DropActiveProcessLimit(base::win::ScopedHandle* job);
// Creates the two tokens with the levels specified in a previous call to // Creates the two tokens with the levels specified in a previous call to
// SetTokenLevel(). Also creates a lowbox token if specified based on the // SetTokenLevel(). Also creates a lowbox token if specified based on the
// lowbox SID. // lowbox SID.
......
...@@ -139,6 +139,8 @@ enum ResultCode : int { ...@@ -139,6 +139,8 @@ enum ResultCode : int {
SBOX_ERROR_INVALID_WRITE_VARIABLE_SIZE = 58, SBOX_ERROR_INVALID_WRITE_VARIABLE_SIZE = 58,
// Cannot initialize BrokerServices. // Cannot initialize BrokerServices.
SBOX_ERROR_CANNOT_INIT_BROKERSERVICES = 59, SBOX_ERROR_CANNOT_INIT_BROKERSERVICES = 59,
// Cannot update job active process limit.
SBOX_ERROR_CANNOT_UPDATE_JOB_PROCESS_LIMIT = 60,
// Placeholder for last item of the enum. // Placeholder for last item of the enum.
SBOX_ERROR_LAST SBOX_ERROR_LAST
}; };
......
...@@ -38685,6 +38685,7 @@ Called by update_gpu_driver_bug_workaround_entries.py.--> ...@@ -38685,6 +38685,7 @@ Called by update_gpu_driver_bug_workaround_entries.py.-->
<int value="57" label="SBOX_ERROR_CANNOT_WRITE_VARIABLE_VALUE"/> <int value="57" label="SBOX_ERROR_CANNOT_WRITE_VARIABLE_VALUE"/>
<int value="58" label="SBOX_ERROR_INVALID_WRITE_VARIABLE_SIZE"/> <int value="58" label="SBOX_ERROR_INVALID_WRITE_VARIABLE_SIZE"/>
<int value="59" label="SBOX_ERROR_CANNOT_INIT_BROKERSERVICES"/> <int value="59" label="SBOX_ERROR_CANNOT_INIT_BROKERSERVICES"/>
<int value="60" label="SBOX_ERROR_CANNOT_UPDATE_JOB_PROCESS_LIMIT"/>
<int value="1002" label="LAUNCH_RESULT_SUCCESS"/> <int value="1002" label="LAUNCH_RESULT_SUCCESS"/>
<int value="1003" label="LAUNCH_RESULT_FAILURE"/> <int value="1003" label="LAUNCH_RESULT_FAILURE"/>
</enum> </enum>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment