morgan pushed to branch tor-browser-128.8.0esr-14.0-1 at The Tor Project / Applications / Tor Browser

Commits:

1 changed file:

Changes:

  • ipc/chromium/src/chrome/common/ipc_channel_win.cc
    ... ... @@ -30,6 +30,34 @@
    30 30
     
    
    31 31
     using namespace mozilla::ipc;
    
    32 32
     
    
    33
    +namespace {
    
    34
    +
    
    35
    +// This logic is borrowed from Chromium's `base/win/win_util.h`. It allows us
    
    36
    +// to distinguish pseudo-handle values, such as returned by GetCurrentProcess()
    
    37
    +// (-1), GetCurrentThread() (-2), and potentially more. The code there claims
    
    38
    +// that fuzzers have found issues up until -12 with DuplicateHandle.
    
    39
    +//
    
    40
    +// https://source.chromium.org/chromium/chromium/src/+/36dbbf38697dd1e23ef8944bb9e57f6e0b3d41ec:base/win/win_util.h
    
    41
    +inline bool IsPseudoHandle(HANDLE handle) {
    
    42
    +  auto handleValue = static_cast<int32_t>(reinterpret_cast<uintptr_t>(handle));
    
    43
    +  return -12 <= handleValue && handleValue < 0;
    
    44
    +}
    
    45
    +
    
    46
    +// A real handle is a handle that is not a pseudo-handle. Always preferably use
    
    47
    +// this variant over ::DuplicateHandle. Only use stock ::DuplicateHandle if you
    
    48
    +// explicitly need the ability to duplicate a pseudo-handle.
    
    49
    +inline bool DuplicateRealHandle(HANDLE source_process, HANDLE source_handle,
    
    50
    +                                HANDLE target_process, LPHANDLE target_handle,
    
    51
    +                                DWORD desired_access, BOOL inherit_handle,
    
    52
    +                                DWORD options) {
    
    53
    +  MOZ_RELEASE_ASSERT(!IsPseudoHandle(source_handle));
    
    54
    +  return static_cast<bool>(::DuplicateHandle(
    
    55
    +      source_process, source_handle, target_process, target_handle,
    
    56
    +      desired_access, inherit_handle, options));
    
    57
    +}
    
    58
    +
    
    59
    +}  // namespace
    
    60
    +
    
    33 61
     namespace IPC {
    
    34 62
     //------------------------------------------------------------------------------
    
    35 63
     
    
    ... ... @@ -595,7 +623,7 @@ bool Channel::ChannelImpl::AcceptHandles(Message& msg) {
    595 623
       nsTArray<mozilla::UniqueFileHandle> handles(num_handles);
    
    596 624
       for (uint32_t handleValue : payload) {
    
    597 625
         HANDLE ipc_handle = Uint32ToHandle(handleValue);
    
    598
    -    if (!ipc_handle || ipc_handle == INVALID_HANDLE_VALUE) {
    
    626
    +    if (!ipc_handle || IsPseudoHandle(ipc_handle)) {
    
    599 627
           CHROMIUM_LOG(ERROR)
    
    600 628
               << "Attempt to accept invalid or null handle from process "
    
    601 629
               << other_pid_ << " for message " << msg.name() << " in AcceptHandles";
    
    ... ... @@ -613,9 +641,10 @@ bool Channel::ChannelImpl::AcceptHandles(Message& msg) {
    613 641
             CHROMIUM_LOG(ERROR) << "other_process_ is invalid in AcceptHandles";
    
    614 642
             return false;
    
    615 643
           }
    
    616
    -      if (!::DuplicateHandle(other_process_, ipc_handle, GetCurrentProcess(),
    
    617
    -                             getter_Transfers(local_handle), 0, FALSE,
    
    618
    -                             DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) {
    
    644
    +      if (!DuplicateRealHandle(
    
    645
    +              other_process_, ipc_handle, GetCurrentProcess(),
    
    646
    +              getter_Transfers(local_handle), 0, FALSE,
    
    647
    +              DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) {
    
    619 648
             DWORD err = GetLastError();
    
    620 649
             // Don't log out a scary looking error if this failed due to the target
    
    621 650
             // process terminating.
    
    ... ... @@ -688,9 +717,9 @@ bool Channel::ChannelImpl::TransferHandles(Message& msg) {
    688 717
             CHROMIUM_LOG(ERROR) << "other_process_ is invalid in TransferHandles";
    
    689 718
             return false;
    
    690 719
           }
    
    691
    -      if (!::DuplicateHandle(GetCurrentProcess(), local_handle.get(),
    
    692
    -                             other_process_, &ipc_handle, 0, FALSE,
    
    693
    -                             DUPLICATE_SAME_ACCESS)) {
    
    720
    +      if (!DuplicateRealHandle(GetCurrentProcess(), local_handle.get(),
    
    721
    +                               other_process_, &ipc_handle, 0, FALSE,
    
    722
    +                               DUPLICATE_SAME_ACCESS)) {
    
    694 723
             DWORD err = GetLastError();
    
    695 724
             // Don't log out a scary looking error if this failed due to the target
    
    696 725
             // process terminating.