Closed Bug 1599008 (CVE-2019-17021) Opened 5 years ago Closed 4 years ago

Race condition in firefox!sandbox::CopyPolicyToTarget leading to Information Disclosure of broker heap address

Categories

(Core :: Security: Process Sandboxing, defect, P1)

All
Windows
defect

Tracking

()

RESOLVED FIXED
mozilla73
Tracking Status
firefox-esr68 72+ fixed
firefox70 --- wontfix
firefox71 --- wontfix
firefox72 --- fixed
firefox73 --- fixed

People

(Reporter: mastho64, Assigned: bobowen)

References

Details

(Keywords: csectype-disclosure, sec-moderate, Whiteboard: [fix in bug 1599005][reporter-external] [client-bounty-form] [verif?][adv-main72+][adv-esr68.4+])

Attachments

(2 files, 1 obsolete file)

Attached file race.zip

Hi,

These issues only affects Windows client, I found two race condition in the shared memory of Firefox sandbox implementation.

  • Information Disclosure of broker heap address in CopyPolicyToTarget (described in this issue)
  • Memory corruption (Sandbox escape) in sandbox::SharedMemIPCServer::ThreadPingEventReady (described in issue 1599005)

Vulnerability:

Since Firefox (current version tested 70.0.1) configures the renderer sandbox with USER_LIMITED and Initial Integrity Level == Delayed Integrity Level (INTEGRITY_LEVEL_LOW), any renderer process can interact with other renderers process (read/write/createthread/duplicatehandles) even while new renderer process bootstrapping (when a new tab process is spawned).
Google Chrome is not affected because the renderer processes runs with a USER_LOCKDOWN token (also the initial integrity level = LOW and delayed IL is UNTRUSTED) which prevent access to other renderer processes.

The race condition vulnerability happens during new process bootstrapping, when a new tab process is created, the broker does:
1/ CreateProcess SUSPENDED with the lockdown token (USER_LIMITED for Firefox renderer) and low IL in TargetProcess::Create
2/ Assign target process to JOB object
3/ Change target thread token to initial token (USER_RESTRICTED_SAME_ACCESS) for initialisation later
4/ Create IPCServer shared memory in TargetProcess::Init
5/ DuplicateHandle the shared memory with the target in TargetProcess::Init
6/ Copy policy and update pointers in CopyPolicyToTarget

So, the target process is suspended but other tabs are not and they can access the target process (thanks to USER_LIMITED token and same IL) and duplicate the IPC shared memory handle.
A race condition exists when the policy is copied to the shared memory (containing broker heap addresses) before it updates policy->entry[i] pointers in CopyPolicyToTarget (6):
void CopyPolicyToTarget(const void* source, size_t size, void* dest) {
if (!source || !size)
return;
memcpy(dest, source, size); // (A) dest is shared memory and source contains broker heap pointers
sandbox::PolicyGlobal* policy =
reinterpret_cast<sandbox::PolicyGlobal*>(dest);

size_t offset = reinterpret_cast<size_t>(source);

for (size_t i = 0; i < sandbox::kMaxServiceCount; i++) {
size_t buffer = reinterpret_cast<size_t>(policy->entry[i]);
if (buffer) {
buffer -= offset;
policy->entry[i] = reinterpret_cast<sandbox::PolicyBuffer*>(buffer); // (B) remove the pointer base (race condition allows disclosure of heap address)
}
}
}

Source code:
https://github.com/mozilla/gecko-dev/blob/master/security/sandbox/chromium/sandbox/win/src/target_process.cc#L33

So, a compromised renderer can read the policy entries pointers before they are updated and it discloses broker heap addresses.

Repro:

The provided POC (attachment payload_infoleak) often triggers the vulnerability.
Install Python 2.7 64 bits and PythonForWindows (https://github.com/hakril/PythonForWindows) then run inject.py with the payload_infoleak.dll path.
Debug the injected tab to verify the information disclosure (in debug output).
Then start new tabs to trigger the vulnerability (like a regular user would do) until it works.

RaceItLeak entry
Leaked worked: dp payload_infoleak!leak_heap L1: 0000022D3486B198
(4220.3bdc): Break instruction exception - code 80000003 (first chance)
KERNELBASE!wil::details::DebugBreak+0x2:
00007ff9`b3720192 cc int 3

The address is a valid heap address in the broker process (you can verify using !address in the broker).
This information disclosure vulnerability allows an attacker to collect information that discloses the memory layout.
In turn the attacker could use this information to deliver tailored exploits to bypass memory protection technologies such as ASLR for an additional LPE/RCE vulnerability.

Thank you

Flags: sec-bounty?
Group: firefox-core-security → core-security
Component: Security → Security: Process Sandboxing
Product: Firefox → Core

Bob, do you know who might be able to take a look at this? Thanks.

Flags: needinfo?(bobowencode)
See Also: → CVE-2019-17015
Type: task → defect

Picking this up in bug 1599005.

Assignee: nobody → bobowencode
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Flags: needinfo?(bobowencode)
OS: Unspecified → Windows
Priority: -- → P1
Hardware: Unspecified → All

(In reply to Bob Owen (:bobowen) from comment #2)

Picking this up in bug 1599005.

I'm interpreting this to mean that this is a separate issue from bug 1599005, but the patch you are posting there will fix both issues.

Depends on: CVE-2019-17015
See Also: CVE-2019-17015

Dan, what should the rating for this bug be? If I'm reading this correctly, this leaks parent process addresses to the child process, if the child process already has arbitrary code execution. Thanks.

Flags: needinfo?(dveditz)

(In reply to Andrew McCreight [:mccr8] from comment #3)

(In reply to Bob Owen (:bobowen) from comment #2)

Picking this up in bug 1599005.

I'm interpreting this to mean that this is a separate issue from bug 1599005, but the patch you are posting there will fix both issues.

That's correct.

(In reply to Andrew McCreight [:mccr8] from comment #4)

Dan, what should the rating for this bug be?

A memory leak of an address (as opposed to large chunks of potentially sensitive user data) on its own is sec-moderate: a stepping stone used as part of an exploit chain.

Group: core-security → dom-core-security
Flags: needinfo?(dveditz)
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [fix in bug 1599005][reporter-external] [client-bounty-form] [verif?]

Bug 1599005 is now landed in 72 and 73.

Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla73
Whiteboard: [fix in bug 1599005][reporter-external] [client-bounty-form] [verif?] → [fix in bug 1599005][reporter-external] [client-bounty-form] [verif?][adv-main72+][adv-esr68.4+]
Attached file advisory.txt
Attachment #9118591 - Attachment is obsolete: true
Flags: sec-bounty? → sec-bounty+
Alias: CVE-2019-17021
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: