diff --git a/snapshot/win/process_reader_win.cc b/snapshot/win/process_reader_win.cc index b7bae6ac..f8a2f928 100644 --- a/snapshot/win/process_reader_win.cc +++ b/snapshot/win/process_reader_win.cc @@ -57,6 +57,7 @@ process_types::SYSTEM_PROCESS_INFORMATION* GetProcessInformation( HANDLE process_handle, std::unique_ptr* buffer) { ULONG buffer_size = 16384; + ULONG actual_size; buffer->reset(new uint8_t[buffer_size]); NTSTATUS status; // This must be in retry loop, as we're racing with process creation on the @@ -66,13 +67,19 @@ process_types::SYSTEM_PROCESS_INFORMATION* GetProcessInformation( SystemProcessInformation, reinterpret_cast(buffer->get()), buffer_size, - &buffer_size); + &actual_size); if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) { + DCHECK_GT(actual_size, buffer_size); + // Add a little extra to try to avoid an additional loop iteration. We're // racing with system-wide process creation between here and the next call // to NtQuerySystemInformation(). - buffer_size += 4096; + buffer_size = actual_size + 4096; + + // Free the old buffer before attempting to allocate a new one. + buffer->reset(); + buffer->reset(new uint8_t[buffer_size]); } else { break; @@ -84,6 +91,8 @@ process_types::SYSTEM_PROCESS_INFORMATION* GetProcessInformation( return nullptr; } + DCHECK_LE(actual_size, buffer_size); + process_types::SYSTEM_PROCESS_INFORMATION* process = reinterpret_cast*>( buffer->get()); diff --git a/util/win/process_info.cc b/util/win/process_info.cc index cb2051c0..f0e455db 100644 --- a/util/win/process_info.cc +++ b/util/win/process_info.cc @@ -157,6 +157,10 @@ std::unique_ptr QueryObject( if (status == STATUS_INFO_LENGTH_MISMATCH) { DCHECK_GT(return_length, size); size = return_length; + + // Free the old buffer before attempting to allocate a new one. + buffer.reset(); + buffer.reset(new uint8_t[size]); status = crashpad::NtQueryObject( handle, object_information_class, buffer.get(), size, &return_length); @@ -167,6 +171,7 @@ std::unique_ptr QueryObject( return nullptr; } + DCHECK_LE(return_length, size); DCHECK_GE(return_length, minimum_size); return buffer; }