Closed Bug 1670358 (CVE-2020-26960) Opened 4 years ago Closed 4 years ago

Calling Compact on a nsTArray will lead to use-after-free error in JS_GC because of the reallocation

Categories

(Core :: JavaScript: GC, defect, P1)

defect

Tracking

()

RESOLVED FIXED
84 Branch
Tracking Status
firefox-esr78 83+ fixed
firefox81 --- wontfix
firefox82 --- wontfix
firefox83 + fixed
firefox84 + fixed

People

(Reporter: ziz353, Assigned: jonco)

References

(Regression)

Details

(4 keywords, Whiteboard: [adv-main83+][adv-esr78.5+])

Attachments

(4 files, 1 obsolete file)

Attached file test_and_output.zip

Version

commit	62c443a7c801ba9672de34c2867ec1665a4bbe67
parent	b2dee52fd392f7130bc3858a70c683faa773aa8f
hg	48f10c4139655c2c4d52fa773f1fd760ea681d42
git	62c443a7c801ba9672de34c2867ec1665a4bbe67
author	Gijs Kruitbosch <gijskruitbosch@gmail.com>
committer	Gijs Kruitbosch <gijskruitbosch@gmail.com>
commit time	Fri, 11 Sep 2020 15:05:50 +0000

Steps to reproduce

More details

The key intuition is that the added Compact will cause the array to reallocate
and trying to access array items using an old address will lead to use-after-free error.

We came across this when we were working on something similar to a ChaosMode feature where we wanted to make array reallocation happen more often.


We have attached a test file with some print statements and the output file.

Our output file shows that the error happens when RunTest is first called with a nsTArray at line 96.

Our output file also shows that reallocation happened several times in the loop line 52-58,
which indicates that the extra reallocation triggered by Compact should not
affect later code.

Before being populated, the array was passed to JS_AddExtraGCRootsTracer
together with TraceArray at line 44.

In TraceArray, we found an unsafe use of addresses of array items.

template <class ArrayT>
static void TraceArray(JSTracer* trc, void* data) {
  ArrayT* array = static_cast<ArrayT*>(data);
  for (unsigned i = 0; i < array->Length(); ++i)
    JS::TraceEdge(trc, &array->ElementAt(i), "array-element");
}

Here, &array->ElementAt(i) will become an invalid address if the array gets reallocated.
We added a print statement in TraceArray but didn't see it in the output file.
This could mean that there are other similarly unsafe code in JS_GC.

We also dumped all the array addresses and saw that
the UAF read is accessing the address right before the last reallocation from Compact.
The UAF address is the last element in the array but we don't know if the last one
is different from other elements.

We think there might be unsafe use of array addresses in the GC code or
the way Compact reallocates array is problematic.

Group: core-security
Group: core-security → dom-core-security
Flags: needinfo?(jcoppeard)

This is kind of XPCOM, but I think barriers generally fall under GC, so I'll move it there.

Group: dom-core-security → javascript-core-security
Component: XPCOM → JavaScript: GC

(In reply to Zijie Zhao from comment #0)
Thank you for reporting this problem.

Assignee: nobody → jcoppeard
Severity: -- → S3
Flags: needinfo?(jcoppeard) → sec-bounty?
Keywords: sec-high
Priority: -- → P1
Regressed by: 877762
Has Regression Range: --- → yes

My original patch handled the grow case but not the shrink case. When the
current and new allocation sizes are in different size classes jemalloc's
realloc will move the allocation when shrinking, not just truncate the existing
one.

Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

Comment on attachment 9181792 [details]
Bug 1670358 - Don't use realloc for shrinking nsTArrays and similar when RelocationStrategy::allowRealloc is false r?mccr8

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Very difficult.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which older supported branches are affected by this flaw?: All of them
  • If not all supported branches, which bug introduced the flaw?: Bug 877762
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: Should be trivial.
  • How likely is this patch to cause regressions; how much testing does it need?: Unlikely; this does the same in the shrink case as the grow case and that code has been there for years.
Attachment #9181792 - Flags: sec-approval?
Attachment #9182867 - Flags: sec-approval?

Comment on attachment 9182867 [details]
Bug 1670358 - Add test for shrinking nsTArrays of JS::Heap<T> r=sg

Approved to land and uplift. I don't see a reason to delay landing the test, so let's just do it now and avoid the possibility of forgetting. (And the associated cost of 'land this later'...)

Attachment #9182867 - Flags: sec-approval?
Attachment #9182867 - Flags: sec-approval+
Attachment #9182867 - Flags: approval-mozilla-esr78+
Attachment #9182867 - Flags: approval-mozilla-beta+

Comment on attachment 9181792 [details]
Bug 1670358 - Don't use realloc for shrinking nsTArrays and similar when RelocationStrategy::allowRealloc is false r?mccr8

Approved to land and uplift.

Attachment #9181792 - Flags: sec-approval?
Attachment #9181792 - Flags: sec-approval+
Attachment #9181792 - Flags: approval-mozilla-esr78+
Attachment #9181792 - Flags: approval-mozilla-beta+
Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch

Since we don't know of a case where this is reachable from the web (the POC required modifying C++ test code) sec-moderate seems a more appropriate rating.

Flags: sec-bounty? → sec-bounty+
Keywords: sec-highsec-moderate
Whiteboard: [adv-main83+]
Attached file advisory.txt (obsolete) —
Attached file advisory.txt
Attachment #9186750 - Attachment is obsolete: true
Whiteboard: [adv-main83+] → [adv-main83+][adv-esr78.5+]
Alias: CVE-2020-26960
Regressions: 1678309
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: