Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2624)

Unified Diff: client/crashpad_client_win.cc

Issue 1427273003: win: Make StartHandler() restrict HANDLES inherited by crashpad_handler (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/crashpad_client_win.cc
diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc
index 46b613726b8b1a9ac49606b94d5dc509de04ee5a..13ef3d622117755d768a9be6ddd2da5f485a9ba0 100644
--- a/client/crashpad_client_win.cc
+++ b/client/crashpad_client_win.cc
@@ -19,6 +19,8 @@
#include "base/atomicops.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/scoped_generic.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -26,6 +28,7 @@
#include "util/file/file_io.h"
#include "util/win/command_line.h"
#include "util/win/critical_section_with_debug_info.h"
+#include "util/win/get_function.h"
#include "util/win/handle.h"
#include "util/win/registration_protocol_win.h"
#include "util/win/scoped_handle.h"
@@ -110,6 +113,40 @@ std::wstring FormatArgumentString(const std::string& name,
return std::wstring(L"--") + base::UTF8ToUTF16(name) + L"=" + value;
}
+struct ScopedProcThreadAttributeListTraits {
+ static PPROC_THREAD_ATTRIBUTE_LIST InvalidValue() {
+ return nullptr;
+ }
+
+ static void Free(PPROC_THREAD_ATTRIBUTE_LIST proc_thread_attribute_list) {
+ // This is able to use GET_FUNCTION_REQUIRED() instead of GET_FUNCTION()
+ // because it will only be called if InitializeProcThreadAttributeList() and
+ // UpdateProcThreadAttribute() are present.
+ static const auto delete_proc_thread_attribute_list =
+ GET_FUNCTION_REQUIRED(L"kernel32.dll", ::DeleteProcThreadAttributeList);
+ delete_proc_thread_attribute_list(proc_thread_attribute_list);
+ }
+};
+
+using ScopedProcThreadAttributeList =
+ base::ScopedGeneric<PPROC_THREAD_ATTRIBUTE_LIST,
+ ScopedProcThreadAttributeListTraits>;
+
+// Adds |handle| to |handle_list| if it appears valid.
+//
+// Invalid handles (including INVALID_HANDLE_VALUE and null handles) cannot be
+// added to a PPROC_THREAD_ATTRIBUTE_LIST’s PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
+// If INVALID_HANDLE_VALUE appears, CreateProcess() will fail with
+// ERROR_INVALID_PARAMETER. If a null handle appears, the child process will
+// silently not inherit any handles.
+//
+// Use this function to add handles with uncertain validities.
+void AddHandleToListIfValid(std::vector<HANDLE>* handle_list, HANDLE handle) {
+ if (handle && handle != INVALID_HANDLE_VALUE) {
+ handle_list->push_back(handle);
+ }
+}
+
} // namespace
namespace crashpad {
@@ -172,22 +209,85 @@ bool CrashpadClient::StartHandler(
HandleToInt(pipe_write))),
&command_line);
- STARTUPINFO startup_info = {};
- startup_info.cb = sizeof(startup_info);
- startup_info.dwFlags = STARTF_USESTDHANDLES;
- startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
- startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ DWORD creation_flags;
+ STARTUPINFOEX startup_info = {};
+ startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ startup_info.StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ startup_info.StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ std::vector<HANDLE> handle_list;
+ scoped_ptr<uint8_t[]> proc_thread_attribute_list_storage;
+ ScopedProcThreadAttributeList proc_thread_attribute_list_owner;
+
+ static const auto initialize_proc_thread_attribute_list =
+ GET_FUNCTION(L"kernel32.dll", ::InitializeProcThreadAttributeList);
scottmg 2015/11/06 20:15:02 Probably don't need :: on these?
Mark Mentovai 2015/11/06 21:49:09 scottmg wrote:
scottmg 2015/11/06 21:53:34 OK, that's fine then too.
+ static const auto update_proc_thread_attribute =
+ initialize_proc_thread_attribute_list
+ ? GET_FUNCTION(L"kernel32.dll", ::UpdateProcThreadAttribute)
+ : nullptr;
+ if (!initialize_proc_thread_attribute_list || !update_proc_thread_attribute) {
+ // The OS doesn’t allow handle inheritance to be restricted, so the handler
+ // will inherit every inheritable handle.
+ creation_flags = 0;
+ startup_info.StartupInfo.cb = sizeof(startup_info.StartupInfo);
+ } else {
+ // Restrict handle inheritance to just those needed in the handler.
+
+ creation_flags = EXTENDED_STARTUPINFO_PRESENT;
+ startup_info.StartupInfo.cb = sizeof(startup_info);
+ SIZE_T size;
+ rv = initialize_proc_thread_attribute_list(nullptr, 1, 0, &size);
+ if (rv) {
+ LOG(ERROR) << "InitializeProcThreadAttributeList (size) succeeded, "
+ "expected failure";
+ return false;
+ } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ PLOG(ERROR) << "InitializeProcThreadAttributeList (size)";
+ return false;
+ }
+
+ proc_thread_attribute_list_storage.reset(new uint8_t[size]);
+ startup_info.lpAttributeList =
+ reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(
+ proc_thread_attribute_list_storage.get());
+ rv = initialize_proc_thread_attribute_list(
+ startup_info.lpAttributeList, 1, 0, &size);
+ if (!rv) {
+ PLOG(ERROR) << "InitializeProcThreadAttributeList";
+ return false;
+ }
+ proc_thread_attribute_list_owner.reset(startup_info.lpAttributeList);
+
+ handle_list.reserve(4);
+ handle_list.push_back(pipe_write);
+ AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdInput);
+ AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdOutput);
+ AddHandleToListIfValid(&handle_list, startup_info.StartupInfo.hStdError);
+ rv = update_proc_thread_attribute(
+ startup_info.lpAttributeList,
+ 0,
+ PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
+ &handle_list[0],
+ handle_list.size() * sizeof(handle_list[0]),
+ nullptr,
+ nullptr);
+ if (!rv) {
+ PLOG(ERROR) << "UpdateProcThreadAttribute";
+ return false;
+ }
+ }
+
PROCESS_INFORMATION process_info;
rv = CreateProcess(handler.value().c_str(),
&command_line[0],
nullptr,
nullptr,
true,
- 0,
+ creation_flags,
nullptr,
nullptr,
- &startup_info,
+ &startup_info.StartupInfo,
&process_info);
if (!rv) {
PLOG(ERROR) << "CreateProcess";
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698