morgan pushed to branch tor-browser-115.21.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits: 2299557b by Yannis Juglaret at 2025-03-26T21:53:05+00:00 Bug 1956398 - Avoid duplicating pseudo-handles in ipc_channel_win.cc.
Differential Revision: https://phabricator.services.mozilla.com/D243189
- - - - -
1 changed file:
- ipc/chromium/src/chrome/common/ipc_channel_win.cc
Changes:
===================================== ipc/chromium/src/chrome/common/ipc_channel_win.cc ===================================== @@ -27,6 +27,34 @@
using namespace mozilla::ipc;
+namespace { + +// This logic is borrowed from Chromium's `base/win/win_util.h`. It allows us +// to distinguish pseudo-handle values, such as returned by GetCurrentProcess() +// (-1), GetCurrentThread() (-2), and potentially more. The code there claims +// that fuzzers have found issues up until -12 with DuplicateHandle. +// +// https://source.chromium.org/chromium/chromium/src/+/36dbbf38697dd1e23ef8944b... +inline bool IsPseudoHandle(HANDLE handle) { + auto handleValue = static_cast<int32_t>(reinterpret_cast<uintptr_t>(handle)); + return -12 <= handleValue && handleValue < 0; +} + +// A real handle is a handle that is not a pseudo-handle. Always preferably use +// this variant over ::DuplicateHandle. Only use stock ::DuplicateHandle if you +// explicitly need the ability to duplicate a pseudo-handle. +inline bool DuplicateRealHandle(HANDLE source_process, HANDLE source_handle, + HANDLE target_process, LPHANDLE target_handle, + DWORD desired_access, BOOL inherit_handle, + DWORD options) { + MOZ_RELEASE_ASSERT(!IsPseudoHandle(source_handle)); + return static_cast<bool>(::DuplicateHandle( + source_process, source_handle, target_process, target_handle, + desired_access, inherit_handle, options)); +} + +} // namespace + namespace IPC { //------------------------------------------------------------------------------
@@ -732,9 +760,9 @@ bool Channel::ChannelImpl::AcceptHandles(Message& msg) { CHROMIUM_LOG(ERROR) << "other_process_ is invalid in AcceptHandles"; return false; } - if (!::DuplicateHandle(other_process_, handle, GetCurrentProcess(), - &handle, 0, FALSE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { + if (!::DuplicateRealHandle( + other_process_, handle, GetCurrentProcess(), &handle, 0, FALSE, + DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { CHROMIUM_LOG(ERROR) << "DuplicateHandle failed for handle " << handle << " in AcceptHandles"; return false; @@ -787,9 +815,9 @@ bool Channel::ChannelImpl::TransferHandles(Message& msg) { CHROMIUM_LOG(ERROR) << "other_process_ is invalid in TransferHandles"; return false; } - if (!::DuplicateHandle(GetCurrentProcess(), handle, other_process_, - &handle, 0, FALSE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { + if (!::DuplicateRealHandle( + GetCurrentProcess(), handle, other_process_, &handle, 0, FALSE, + DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) { CHROMIUM_LOG(ERROR) << "DuplicateHandle failed for handle " << handle << " in TransferHandles"; return false;
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/2299557b...
tor-commits@lists.torproject.org