Closed Bug 1176270 (CVE-2015-4488) Opened 9 years ago Closed 9 years ago

StyleAnimationValue::operator= uses objects after delete on self-assignment

Categories

(Core :: Layout, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla41
Tracking Status
firefox39 --- wontfix
firefox40 --- fixed
firefox41 --- fixed
firefox-esr31 --- wontfix
firefox-esr38 40+ fixed
b2g-v2.0 --- wontfix
b2g-v2.0M --- wontfix
b2g-v2.1 --- wontfix
b2g-v2.1S --- wontfix
b2g-v2.2 --- fixed
b2g-master --- fixed

People

(Reporter: q1, Assigned: dholbert)

Details

(Keywords: sec-low, Whiteboard: [b2g-adv-main2.2+][post-critsmash-triage][adv-main40+][adv-esr38.2+])

Attachments

(2 files)

On self-assignment, StyleAnimationValue::operator= deletes an object, then creates a new object from the deleted object's freed memory. 3558: StyleAnimationValue& 3559: StyleAnimationValue::operator=(const StyleAnimationValue& aOther) 3560: { 3561: FreeValue(); 3562: mUnit = aOther.mUnit; 3563: switch (mUnit) { ... 3586: case eUnit_Calc: 3587: case eUnit_ObjectPosition: 3588: MOZ_ASSERT(IsCSSValueUnit(mUnit), 3589: "This clause is for handling nsCSSValue-backed units"); 3590: MOZ_ASSERT(aOther.mValue.mCSSValue, "values may not be null"); 3591: mValue.mCSSValue = new nsCSSValue(*aOther.mValue.mCSSValue); 3592: break; ... 3637: }; 3786: void 3787: StyleAnimationValue::FreeValue() 3788: { 3789: if (IsCSSValueUnit(mUnit)) { 3790: delete mValue.mCSSValue; 3791: } else if (IsCSSValueListUnit(mUnit)) { 3792: delete mValue.mCSSValueList; 3793: } else if (IsCSSValueSharedListValue(mUnit)) { 3794: mValue.mCSSValueSharedList->Release(); 3795: } else if (IsCSSValuePairUnit(mUnit)) { 3796: delete mValue.mCSSValuePair; 3797: } else if (IsCSSValueTripletUnit(mUnit)) { 3798: delete mValue.mCSSValueTriplet; 3799: } else if (IsCSSRectUnit(mUnit)) { 3800: delete mValue.mCSSRect; 3801: } else if (IsCSSValuePairListUnit(mUnit)) { 3802: delete mValue.mCSSValuePairList; 3803: } else if (IsStringUnit(mUnit)) { 3804: MOZ_ASSERT(mValue.mString, "expecting non-null string"); 3805: mValue.mString->Release(); 3806: } 3807: } operator = mishandles all of the cases in which an object is deleted or Released by FreeValue, using the deleted/Released object *aOther.mValue.* as the source for the creation of a new object.
In the case of eUnit_Transform and eUnit_UnparsedString, instead of creating a new object, the code AddRefs the Released object, which can be a deleted object.
Component: Untriaged → Layout
Product: Firefox → Core
(This is 38.0.1\layout\style\StyleAnimationValue.cpp/.h)
Assignee: nobody → dholbert
Version: 38 Branch → Trunk
Attached patch fix v1Splinter Review
Thanks for the bug report! I suspect we don't ever *actually* self-assign these structs, though I'm not 100% sure. Anyway, we definitely should handle this case, for robustness/safety. Here's a simple patch, handling self-assignment with an early-return, as recommended in (2) of https://isocpp.org/wiki/faq/assignment-operators#self-assignment-how (I don't think there's a more graceful/efficient way to make self-assignment simply Just Work with the existing code, due to the need to clean up our previous contents.)
Attachment #8624818 - Flags: review?(dbaron)
Looks like this issue goes back to 2009, from bug 522852: http://hg.mozilla.org/mozilla-central/rev/2072cf8f65b4#l2.542 We probably should take this patch on all supported branches, to be on the safe side.
Comment on attachment 8624818 [details] [diff] [review] fix v1 r=dbaron; this is the standard way to handle this
Attachment #8624818 - Flags: review?(dbaron) → review+
I did an audit locally, to see if we can ever get self-assignment (i.e. if this is possible to exploit). I've convinced myself that it's not possible, and hence that we're safe. I'm attaching the auditing patch that I used to convince myself. I just replaced the operator= decl with "operator=(...) = delete;", so that each usage of the reassignment operator would turn into a build error. And then I checked the conditions around each usage, and proved to myself that none of these instances can be a self-assignment. Then I commented out the assignment (so I could proceed with the build), and waited for the next build error. This patch builds, which means I found all the usages. Comments are included next to each commented-out assignment, indicating why I'm sure we're safe at that spot. (Please feel free to sanity-check my reasoning.)
(Note that my auditing patch deletes the (implicitly-defined) reassignment operator for "ValueWrapper" in nsSMILCSSValueType. That implicitly-defined reassignment operator uses the StyleAnimationValue assignment operator, because ValueWrapper has a StyleAnimationValue member-var.)
So I don't think this is actually exploitable, per comment 6. But to be on the safe side, I still think we should keep this bug hidden & go through the sec-approval process, and that we should backport the patch to affected branches, in the unlikely event that I made a mistake in my auditing, or that my trunk auditing doesn't cover some other usage of this assignment operator in an older still-supported Firefox release. (Plus, it's an extremely-safe fix, which can only improve safety/stability.)
Keywords: sec-low
RyanVM & dveditz confirm that I should skip sec-approval and just go ahead and land, actually, given that this is sec-low / extremely-unlikely-to-be-exploitable (per comment 6). (sec-approval process is only for high/crit)
(In reply to Daniel Holbert [:dholbert] from comment #6) > Created attachment 8624886 [details] [diff] [review] > dummy patch for auditing > > I did an audit locally, to see if we can ever get self-assignment (i.e. if > this is possible to exploit). > > I've convinced myself that it's not possible, and hence that we're safe. > ... > Comments are included next to each commented-out assignment, indicating why > I'm sure we're safe at that spot. (Please feel free to sanity-check my > reasoning.) This looks believable. Thank you for checking this out.
(In reply to q1 from comment #10) > This looks believable. Thank you for checking this out. Of course! (Thank you for noticing & filing!)
Comment on attachment 8624818 [details] [diff] [review] fix v1 Approval Request Comment ======================== [Feature/regressing bug #]: This code dates back to bug 522852 (though per comment 6, it's unlikely that this can actually cause any problems). [User impact if declined]: We'll be left with an unsafe coding pattern here. (AFAIK, there's no actual harm, per comment 6, but it's possible I missed something and there might be some way to trigger this case.) [Describe test coverage new/current, TreeHerder]: Patch has landed on inbound and is baking there. We have good test coverage for various types of animations. And I don't think the patch *actually* affects our behavior, per comment 6, since we never invoke this code in a way that would be unsafe. (currently) [Risks and why]: This is as low-risk as it gets. This is adding a safe early-return for a case that we initially missed, to handle a scenario that we don't actually ever hit right now. So, I don't think this even affects current behavior. (But to the extent that it does affect behavior at all, this patch makes us strictly safer/more stable.) [String/UUID change made/needed]: None For ESR31: ========== [If this is not a sec:{high,crit} bug, please state case for ESR consideration:] Trivial patch, which fixes up an unsafe coding pattern & which (to the extent that it has any effect at all) makes us strictly safer/more stable. Might as well just take it on all supported branches, including ESR.
Attachment #8624818 - Flags: approval-mozilla-esr31?
Attachment #8624818 - Flags: approval-mozilla-beta?
Attachment #8624818 - Flags: approval-mozilla-aurora?
Attachment #8624818 - Flags: approval-mozilla-esr38?
Attachment #8624818 - Flags: approval-mozilla-b2g37?
We could still take this for beta for the RC build if it gets sec approval.
I was told not to get sec-approval (per comment 9), given that this is sec-low. For the same reason, let's not scramble to rush this into beta.
Status: NEW → RESOLVED
Closed: 9 years ago
Flags: in-testsuite?
Resolution: --- → FIXED
Target Milestone: --- → mozilla41
Wontfix for 39. This could still make it into 40.
Attachment #8624818 - Flags: approval-mozilla-beta?
Comment on attachment 8624818 [details] [diff] [review] fix v1 Taking it for esr 38 because we are in the stability period but not taking it for esr 31 as it is not a critical sec issue.
Attachment #8624818 - Flags: approval-mozilla-esr38?
Attachment #8624818 - Flags: approval-mozilla-esr38+
Attachment #8624818 - Flags: approval-mozilla-esr31?
Attachment #8624818 - Flags: approval-mozilla-esr31-
Attachment #8624818 - Flags: approval-mozilla-aurora?
Attachment #8624818 - Flags: approval-mozilla-aurora+
Comment on attachment 8624818 [details] [diff] [review] fix v1 Approving and please NI if causing any side effect.
Attachment #8624818 - Flags: approval-mozilla-b2g37? → approval-mozilla-b2g37+
Ryan, can you confirm the patch has made it into the 2.2 release?
Flags: needinfo?(ryanvm)
Whiteboard: [b2g-adv-main2.2+]
Comment 21 right above yours and status-b2g-v2.2: fixed say that it did.
Flags: needinfo?(ryanvm)
Whiteboard: [b2g-adv-main2.2+] → [b2g-adv-main2.2+][post-critsmash-triage]
Whiteboard: [b2g-adv-main2.2+][post-critsmash-triage] → [b2g-adv-main2.2+][post-critsmash-triage][adv-main40+][adv-esr38.2+]
Alias: CVE-2015-4488
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: