New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 622522 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
please use my google.com address
Closed: Jun 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug-Security



Sign in to add a comment

Security: unchecked size in mojo::Channel::Deserialize leads to memory corruption.

Project Member Reported by och...@chromium.org, Jun 22 2016

Issue description

In mojo::Channel::Deserialize:

  uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
#if defined(OS_WIN)
  uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) /
      sizeof(MachPortsEntry);
#endif
  if (header->num_handles > max_handles) {
    DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
                << " > " << max_handles;
    return nullptr;
  }

  MessagePtr message(new Message(data_num_bytes - header->num_header_bytes,
                                 max_handles));

There is no check that |header->num_header_bytes| is greater than sizeof(Header), which means extra_header_size could underflow. (For OS_MACOSX, there is also an issue as there is no check that |extra_header_size| is greater than sizeof(MachPortsExtraHeader).

This leads to a large |max_handles| value that gets passed to Channel::Message's constructor. For 32-bit builds, where size_t has the same size as uint32_t, this leads to integer overflow when determining the size for allocating the message buffer:

#if defined(OS_WIN)
  // On Windows we serialize HANDLEs into the extra header space.
  extra_header_size = max_handles_ * sizeof(HandleEntry);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
  // On OSX, some of the platform handles may be mach ports, which are
  // serialised into the message buffer. Since there could be a mix of fds and
  // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
  // so that the original ordering of handles can be re-created.
  if (max_handles) {
    extra_header_size =
        sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
  }
...
size_ = sizeof(Header) + extra_header_size + payload_size;

Leading to buffer overflows afterwards. For the PoC I attached (patch), this gives me an access violation here:

...
  if (max_handles_ > 0) {
#if defined(OS_WIN)
    handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header());
    // Initialize all handles to invalid values.
    for (size_t i = 0; i < max_handles_; ++i)
      handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); <--

...

(1b98.1f8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=07372420 ebx=00000010 ecx=000252f8 edx=3fffffff esi=074b5580 edi=00000000
eip=63143653 esp=062ef7e0 ebp=062ef7e8 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010297
chrome_62560000!mojo::edk::Channel::Message::Message+0x93:
63143653 c70488ffffffff  mov     dword ptr [eax+ecx*4],0FFFFFFFFh ds:002b:07407000=????????
0:014> k
 # ChildEBP RetAddr  
00 062ef7e8 63143786 chrome_62560000!mojo::edk::Channel::Message::Message+0x93 [d:\src\chromium\src\mojo\edk\system\channel.cc @ 104]
01 062ef80c 63145043 chrome_62560000!mojo::edk::Channel::Message::Deserialize+0x66 [d:\src\chromium\src\mojo\edk\system\channel.cc @ 160]
02 062ef8e8 63143bab chrome_62560000!mojo::edk::NodeChannel::OnChannelMessage+0x5a3 [d:\src\chromium\src\mojo\edk\system\node_channel.cc @ 648]
03 062ef9d0 63145f60 chrome_62560000!mojo::edk::Channel::OnReadComplete+0x1fb [d:\src\chromium\src\mojo\edk\system\channel.cc @ 587]
04 062ef9e4 63145ed1 chrome_62560000!mojo::edk::`anonymous namespace'::ChannelWin::OnReadDone+0x20 [d:\src\chromium\src\mojo\edk\system\channel_win.cc @ 243]
05 062efaac 6296a189 chrome_62560000!mojo::edk::`anonymous namespace'::ChannelWin::OnIOCompleted+0x71 [d:\src\chromium\src\mojo\edk\system\channel_win.cc @ 232]
06 (Inline) -------- chrome_62560000!base::MessagePumpForIO::WaitForIOCompletion+0x29 [d:\src\chromium\src\base\message_loop\message_pump_win.cc @ 782]
07 062efadc 6296945e chrome_62560000!base::MessagePumpForIO::WaitForWork+0x49 [d:\src\chromium\src\base\message_loop\message_pump_win.cc @ 764]
08 062efbc0 62969f4a chrome_62560000!base::MessagePumpForIO::DoRunLoop+0xae [d:\src\chromium\src\base\message_loop\message_pump_win.cc @ 726]
09 062efbe8 62924981 chrome_62560000!base::MessagePumpWin::Run+0x4a [d:\src\chromium\src\base\message_loop\message_pump_win.cc @ 143]
0a 062efbf4 62951a85 chrome_62560000!base::MessageLoop::RunHandler+0x11 [d:\src\chromium\src\base\message_loop\message_loop.cc @ 457]
0b 062efc18 6292495d chrome_62560000!base::RunLoop::Run+0x65 [d:\src\chromium\src\base\run_loop.cc @ 36]
0c 062efc3c 62939afb chrome_62560000!base::MessageLoop::Run+0x1d [d:\src\chromium\src\base\message_loop\message_loop.cc @ 296]
0d 062efc44 635009ff chrome_62560000!base::Thread::Run+0xb [d:\src\chromium\src\base\threading\thread.cc @ 205]
0e 062efd10 63501166 chrome_62560000!content::BrowserThreadImpl::IOThreadRun+0x1f [d:\src\chromium\src\content\browser\browser_thread_impl.cc @ 224]
0f 062efddc 62939ead chrome_62560000!content::BrowserThreadImpl::Run+0x166 [d:\src\chromium\src\content\browser\browser_thread_impl.cc @ 259]
10 062efe14 6294b4a2 chrome_62560000!base::Thread::ThreadMain+0x11d [d:\src\chromium\src\base\threading\thread.cc @ 258]
11 062efe30 757338f4 chrome_62560000!base::`anonymous namespace'::ThreadFunc+0x82 [d:\src\chromium\src\base\threading\platform_thread_win.cc @ 85]
12 062efe44 76fa5de3 KERNEL32!BaseThreadInitThunk+0x24
13 062efe8c 76fa5dae ntdll!__RtlUserThreadStart+0x2f
14 062efe9c 00000000 ntdll!_RtlUserThreadStart+0x1b

I *think* on 64-bit there is no obvious way that this could lead to memory corruption (because |max_handles| is truncated to 32-bit before being promoted to size_t again for the allocation size calculation), so realistically this only affects 32-bit Windows builds right now.
 
blah.patch
4.2 KB Download

Comment 1 by och...@chromium.org, Jun 22 2016

Cc: amistry@chromium.org
Owner: roc...@chromium.org
Status: Assigned (was: Unconfirmed)
rockot, amistry, mind taking a look at this? Should be a simple fix, but I wonder if there is a way to consolidate the two Channel::Message deserialization functions (OnReadComplete, and ::Deserialize)?
Project Member

Comment 2 by bugdroid1@chromium.org, Jun 23 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/b794e408d837a01063d9c7f9f2dc549c635fd0fe

commit b794e408d837a01063d9c7f9f2dc549c635fd0fe
Author: rockot <rockot@chromium.org>
Date: Thu Jun 23 01:44:15 2016

[mojo-edk] Fix unchecked header sizes channel messages

BUG= 622522 
R=ochang@chromium.org

Review-Url: https://codereview.chromium.org/2095493003
Cr-Commit-Position: refs/heads/master@{#401510}

[modify] https://crrev.com/b794e408d837a01063d9c7f9f2dc549c635fd0fe/mojo/edk/system/channel.cc

Comment 3 by roc...@chromium.org, Jun 23 2016

Status: Fixed (was: Assigned)
I'll deal with merging to M52 and M51 after it's baked a bit.

Comment 4 by och...@chromium.org, Jun 23 2016

Labels: Security_Severity-High Security_Impact-Stable
Thanks, rockot.
Project Member

Comment 5 by ClusterFuzz, Jun 23 2016

Labels: Merge-Triage M-51 M-52
Adding Merge-Triage label for tracking purposes.

Once your fix had sufficient bake time (on canary, dev as appropriate), please nominate your fix for merge by adding the Merge-Request-XX label, where XX is the Chrome milestone.

When your merge is approved by the release manager, please start merging with higher milestone label first. Make sure to re-request merge for every milestone in the label list. You can get branch information on omahaproxy.appspot.com.

- Your friendly ClusterFuzz
Project Member

Comment 6 by sheriffbot@chromium.org, Jun 23 2016

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 7 by sheriffbot@chromium.org, Jun 25 2016

Labels: Merge-Request-52

Comment 8 by tin...@google.com, Jun 27 2016

Labels: -Merge-Request-52 Merge-Review-52 Hotlist-Merge-Review
[Automated comment] There appears to be on-going work (i.e. bugroid changes), needs manual review.

Comment 9 by gov...@chromium.org, Jun 27 2016

Before we approve merge to M52, Could you please confirm whether this change is baked/verified in Canary and safe to merge?

Also is this change applicable to all OS or any specific OS?
It has baked and it affects all platforms.
Labels: -Merge-Review-52 Merge-Approved-52 OS-All
Approving merge to M52 branch 2743 based on comment #10. Please merge asap. Thank you.
Project Member

Comment 12 by bugdroid1@chromium.org, Jun 28 2016

Labels: -merge-approved-52 merge-merged-2743
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/894e5f1fffbb004b23d663cc89cfa47f48c82fad

commit 894e5f1fffbb004b23d663cc89cfa47f48c82fad
Author: Ken Rockot <rockot@chromium.org>
Date: Tue Jun 28 18:27:50 2016

[mojo-edk] Fix unchecked header sizes channel messages

BUG= 622522 
R=ochang@chromium.org

Review-Url: https://codereview.chromium.org/2095493003
Cr-Commit-Position: refs/heads/master@{#401510}
(cherry picked from commit b794e408d837a01063d9c7f9f2dc549c635fd0fe)

Review URL: https://codereview.chromium.org/2102193002 .

Cr-Commit-Position: refs/branch-heads/2743@{#507}
Cr-Branched-From: 2b3ae3b8090361f8af5a611712fc1a5ab2de53cb-refs/heads/master@{#394939}

[modify] https://crrev.com/894e5f1fffbb004b23d663cc89cfa47f48c82fad/mojo/edk/system/channel.cc

Labels: -Merge-Triage
Labels: Release-0-M52
Project Member

Comment 15 by sheriffbot@chromium.org, Sep 29 2016

Labels: -Restrict-View-SecurityNotify
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 16 by sheriffbot@chromium.org, Oct 1 2016

This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Project Member

Comment 17 by sheriffbot@chromium.org, Oct 2 2016

This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: allpublic
Components: Internals>Mojo
Project Member

Comment 20 by sheriffbot@chromium.org, Jul 28

Labels: Pri-1

Sign in to add a comment