Cache HandlerCloser serialized map
The serialized handle closer map in practice does not change once a given handler closer is initialized. This allows us to cache the serialized map and re-use it across multiple target launches, rather than regenerating it each time. We add a protection to prevent calling AddHandle after the cached map is generated. Bug: 549319 Change-Id: Ic0414e9fcd80e74ed5e485dbed33161c5f09f782 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3821609 Commit-Queue: Alex Gough <ajgo@chromium.org> Reviewed-by: Will Harris <wfh@chromium.org> Cr-Commit-Position: refs/heads/main@{#1043724}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a14cb3284f
commit
02203152be
sandbox/win/src
@ -43,6 +43,11 @@ ResultCode HandleCloser::AddHandle(const wchar_t* handle_type,
|
||||
if (!handle_type)
|
||||
return SBOX_ERROR_BAD_PARAMS;
|
||||
|
||||
// Cannot call AddHandle if the cache has been initialized.
|
||||
DCHECK(serialized_map_.empty());
|
||||
if (!serialized_map_.empty())
|
||||
return SBOX_ERROR_UNEXPECTED_CALL;
|
||||
|
||||
std::wstring resolved_name;
|
||||
if (handle_name) {
|
||||
resolved_name = handle_name;
|
||||
@ -93,17 +98,20 @@ bool HandleCloser::InitializeTargetHandles(TargetProcess& target) {
|
||||
if (handles_to_close_.empty())
|
||||
return true;
|
||||
|
||||
size_t bytes_needed = GetBufferSize();
|
||||
std::unique_ptr<size_t[]> local_buffer(
|
||||
new size_t[bytes_needed / sizeof(size_t)]);
|
||||
// Cache the serialized form as we might be used by shared configs.
|
||||
if (serialized_map_.empty()) {
|
||||
size_t bytes_needed = GetBufferSize();
|
||||
serialized_map_.resize(bytes_needed);
|
||||
|
||||
if (!SetupHandleList(local_buffer.get(), bytes_needed))
|
||||
return false;
|
||||
if (!SetupHandleList(serialized_map_.data(), bytes_needed))
|
||||
return false;
|
||||
}
|
||||
|
||||
void* remote_data;
|
||||
if (!CopyToChildMemory(target.Process(), local_buffer.get(), bytes_needed,
|
||||
&remote_data))
|
||||
if (!CopyToChildMemory(target.Process(), serialized_map_.data(),
|
||||
serialized_map_.size(), &remote_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_handles_to_close = reinterpret_cast<HandleCloserInfo*>(remote_data);
|
||||
|
||||
|
@ -53,9 +53,11 @@ class HandleCloser {
|
||||
// Adds a handle that will be closed in the target process after lockdown.
|
||||
// A nullptr value for handle_name indicates all handles of the specified
|
||||
// type. An empty string for handle_name indicates the handle is unnamed.
|
||||
// Note: this cannot be called after InitializeTargetHandles().
|
||||
ResultCode AddHandle(const wchar_t* handle_type, const wchar_t* handle_name);
|
||||
|
||||
// Serializes and copies the closer table into the target process.
|
||||
// Note: this can be called multiple times for different targets.
|
||||
bool InitializeTargetHandles(TargetProcess& target);
|
||||
|
||||
private:
|
||||
@ -70,6 +72,7 @@ class HandleCloser {
|
||||
bool SetupHandleList(void* buffer, size_t buffer_bytes);
|
||||
|
||||
HandleMap handles_to_close_;
|
||||
std::vector<uint8_t> serialized_map_;
|
||||
};
|
||||
|
||||
} // namespace sandbox
|
||||
|
Reference in New Issue
Block a user