Closed Bug 1289085 (CVE-2016-2827) Opened 9 years ago Closed 9 years ago

Out-of-bounds read in mozilla::net::IsValidReferrerPolicy

Categories

(Core :: DOM: Security, defect, P1)

50 Branch
defect

Tracking

()

VERIFIED FIXED
mozilla50
Tracking Status
firefox48 --- wontfix
firefox49 + verified
firefox-esr45 49+ wontfix
firefox50 + verified

People

(Reporter: attekett, Assigned: ckerschb)

References

Details

(4 keywords, Whiteboard: [domsecurity-active][adv-main49+])

Attachments

(4 files, 1 obsolete file)

Tested on: OS: Ubuntu 14.04 Firefox: ASAN build from https://ftp.mozilla.org/pub/firefox/tinderbox-builds/mozilla-central-linux64-asan/1469354528/ Repro-file as an attachment. ASAN-trace: ==29350==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030005a6150 at pc 0x7fc156120f40 bp 0x7ffdb447f6b0 sp 0x7ffdb447f6a8 READ of size 4 at 0x6030005a6150 thread T0 (Web Content) #0 0x7fc156120f3f in IsEmpty /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTSubstring.h:242:12 #1 0x7fc156120f3f in mozilla::net::IsValidReferrerPolicy(nsAString_internal const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/mozilla/net/ReferrerPolicy.h:93:0 #2 0x7fc156143c10 in nsCSPParser::referrerDirectiveValue() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:917:8 #3 0x7fc156148820 in nsCSPParser::directive() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:1219:3 #4 0x7fc15614956a in nsCSPParser::policy() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:1258:5 #5 0x7fc156121997 in nsCSPParser::parseContentSecurityPolicy(nsAString_internal const&, nsIURI*, bool, nsCSPContext*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:1301:25 #6 0x7fc1561211bb in nsCSPContext::AppendPolicy(nsAString_internal const&, bool, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPContext.cpp:386:25 #7 0x7fc15253ba66 in nsHtml5TreeOpExecutor::AddSpeculationCSP(nsAString_internal const&) /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:1049:8 #8 0x7fc15253b392 in nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor*) /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5SpeculativeLoad.cpp:31:7 #9 0x7fc1525b43ea in nsHtml5TreeOpExecutor::RunFlushLoop() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5TreeOpExecutor.cpp:396:9 #10 0x7fc1525b916b in nsHtml5ExecutorFlusher::Run() /builds/slave/m-cen-l64-asan-000000000000000/build/src/parser/html/nsHtml5StreamParser.cpp:128:9 . . . 0x6030005a6150 is located 8 bytes to the right of 24-byte region [0x6030005a6130,0x6030005a6148) allocated by thread T0 (Web Content) here: #0 0x4b522b in __interceptor_malloc _asan_rtl_:3 #1 0x4e2efd in moz_xmalloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/memory/mozalloc/mozalloc.cpp:83:17 #2 0x7fc15040749d in Malloc /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTArray.h:178:46 #3 0x7fc15040749d in nsTArrayInfallibleAllocator::ResultTypeProxy nsTArray_base<nsTArrayInfallibleAllocator, nsTArray_CopyWithMemutils>::EnsureCapacity<nsTArrayInfallibleAllocator>(unsigned long, unsigned long) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTArray-inl.h:136:0 #4 0x7fc151423f7c in nsString* nsTArray_Impl<nsString, nsTArrayInfallibleAllocator>::ReplaceElementsAt<nsString, nsTArrayInfallibleAllocator>(unsigned long, unsigned long, nsString const*, unsigned long) /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTArray.h:1870:32 #5 0x7fc156149562 in operator= /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTArray.h:891:7 #6 0x7fc156149562 in operator= /builds/slave/m-cen-l64-asan-000000000000000/build/src/obj-firefox/dist/include/nsTArray.h:2057:0 #7 0x7fc156149562 in nsCSPParser::policy() /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:1257:0 #8 0x7fc156121997 in nsCSPParser::parseContentSecurityPolicy(nsAString_internal const&, nsIURI*, bool, nsCSPContext*, bool) /builds/slave/m-cen-l64-asan-000000000000000/build/src/dom/security/nsCSPParser.cpp:1301:25 . . .
Keywords: testcase
Version: unspecified → 50 Branch
christoph: is this only going to read bogus values into a CSP (so a lower severity csp bypass) or is it due to us being so screwed up that we're going to corrupt memory further?
Component: General → DOM: Security
Flags: needinfo?(ckerschb)
(In reply to Daniel Veditz [:dveditz] from comment #1) > christoph: is this only going to read bogus values into a CSP (so a lower > severity csp bypass) or is it due to us being so screwed up that we're going > to corrupt memory further? In this case where a CSP of 'referrer' is delivered without any valid srcs (e.g. it's not delivered like 'referrer no-referrer') our parser is reading a bogus value and tries to convert that value into a valid referrerPolicy. If you run the test in a debug build you actually trigger an assertion (see underneath). Nevertheless, it's not handled gracefully within the CSP parser. Program received signal SIGSEGV, Segmentation fault. 0x00007fffe67ae6f5 in nsTArray_Impl<nsString, nsTArrayInfallibleAllocator>::ElementAt (this=0x7fffffffc160, aIndex=1) at /home/ckerschb/moz/mc-obj-ff-dbg/dist/include/nsTArray.h:992 992 MOZ_ASSERT(aIndex < Length(), "invalid array index"); (gdb) bt #0 0x00007fffe67ae6f5 in nsTArray_Impl<nsString, nsTArrayInfallibleAllocator>::ElementAt (this=0x7fffffffc160, aIndex=1) at /home/ckerschb/moz/mc-obj-ff-dbg/dist/include/nsTArray.h:992 #1 0x00007fffe67acd67 in nsTArray_Impl<nsString, nsTArrayInfallibleAllocator>::operator[] (this=0x7fffffffc160, aIndex=1) at /home/ckerschb/moz/mc-obj-ff-dbg/dist/include/nsTArray.h:1027 #2 0x00007fffe8820707 in nsCSPParser::referrerDirectiveValue (this=0x7fffffffc130) at /home/ckerschb/moz/mc/dom/security/nsCSPParser.cpp:917 #3 0x00007fffe88211ac in nsCSPParser::directiveValue (this=0x7fffffffc130, outSrcs=...) at /home/ckerschb/moz/mc/dom/security/nsCSPParser.cpp:1049 #4 0x00007fffe8821bda in nsCSPParser::directive (this=0x7fffffffc130) at /home/ckerschb/moz/mc/dom/security/nsCSPParser.cpp:1219 #5 0x00007fffe8821e2c in nsCSPParser::policy (this=0x7fffffffc130) at /home/ckerschb/moz/mc/dom/security/nsCSPParser.cpp:1258 #6 0x00007fffe882211d in nsCSPParser::parseContentSecurityPolicy (aPolicyString=..., aSelfURI=0x7fffc514fd00, aReportOnly=false, aCSPContext=0x7fffc48f4ca0, aDeliveredViaMetaTag=true) at /home/ckerschb/moz/mc/dom/security/nsCSPParser.cpp:1301 #7 0x00007fffe8818127 in nsCSPContext::AppendPolicy (this=0x7fffc48f4ca0, aPolicyString=..., aReportOnly=false, aDeliveredViaMetaTag=true) at /home/ckerschb/moz/mc/dom/security/nsCSPContext.cpp:391
Assignee: nobody → ckerschb
Status: NEW → ASSIGNED
Flags: needinfo?(ckerschb)
Priority: -- → P1
Whiteboard: [domsecurity-active]
The problem was introduced within > Bug 965727 - Implement referrer directive for CSP. (r=jst,ckerschb) Bug 965727 checks that the referrer directive does not contain too many srcs but doesn't check if there are not enough [1] - really unfortunate! While investigating the problem related to this bug I also realized that we don't handle 'sandbox', 'report-uri' and also 'require-sri' directives correctly if delivered without a src. In those cases it's not a memory-corruption problem though, because the parser iterates over the remaining srcs instead of indexing into the array (see [2] for example). I filed Bug 1290560 to fix those problems, no need to pollute this patch with those fixes. Also because this patch most likely will be upliftet. [1] https://hg.mozilla.org/mozilla-central/diff/eabee47625c6/dom/security/nsCSPParser.cpp#l1.37 [2] https://dxr.mozilla.org/mozilla-central/source/dom/security/nsCSPParser.cpp#928
Attachment #8776138 - Flags: review?(dveditz)
Group: core-security → dom-core-security
(In reply to Christoph Kerschbaumer [:ckerschb] from comment #2) > our parser is reading a bogus value and tries to convert that value > into a valid referrerPolicy. This doesn't seem particularly exploitable: either it will crash the user or the referrer policy will be invalid and ignored. In rare cases it might match a valid value and change the type of referrer that gets sent.
Comment on attachment 8776138 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src.patch Review of attachment 8776138 [details] [diff] [review]: ----------------------------------------------------------------- r=dveditz if you fix the comments ::: dom/security/nsCSPParser.cpp @@ +913,2 @@ > mCurDir.Length() - 1)); > + delete aDir; I notice that in nsCSPParser::requireSRIForDirectiveValue() the error case does not delete aDir. I think you're right here and we have a leak in the other one so maybe you can fix that in this patch. @@ +1207,5 @@ > > + // special case handling of the referrer directive (since it doesn't contain > + // source lists) > + if (cspDir->equals(nsIContentSecurityPolicy::REFERRER_DIRECTIVE)) { > + referrerDirectiveValue(static_cast<nsRequireSRIForDirective*>(cspDir)); casting to a nsRequireSRIForDirective* can't be right. The method's argument is a nsCSPDirective* and cspDir is already a nsCSPDirective* so I don't think you need the cast, do you?
Attachment #8776138 - Flags: review?(dveditz) → review+
Attachment #8776140 - Flags: review?(dveditz) → review+
(In reply to Daniel Veditz [:dveditz] from comment #6) > > + delete aDir; > > I notice that in nsCSPParser::requireSRIForDirectiveValue() the error case > does not delete aDir. I think you're right here and we have a leak in the > other one so maybe you can fix that in this patch. Yes, there is a leak. I'll fix that within Bug 1290560 as well, since requrire-sri is prefed off by default anyway. > > + referrerDirectiveValue(static_cast<nsRequireSRIForDirective*>(cspDir)); > > casting to a nsRequireSRIForDirective* can't be right. The method's argument > is a nsCSPDirective* and cspDir is already a nsCSPDirective* so I don't > think you need the cast, do you? You are absolutely right, no need for that cast. That was a copy/paste. Thanks for catching.
Attachment #8776138 - Attachment is obsolete: true
Attachment #8776342 - Flags: review+
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
Comment on attachment 8776140 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src_tests.patch Approval Request Comment A webpage sending the CSP policy of only 'referrer' (without any src after the directive) might crash the browser because Firefox is reading a value from out of bounds. [Feature/regressing bug #]: Bug 965727 - Implement CSP 1.1 referrer directive [User impact if declined]: I don't know how many sites would send a CSP policy of 'referrer' only, but the fact that a security feature might crash the browser makes me feel we should uplift the fix within this bug. [Describe test coverage new/current, TreeHerder]: Landed a compiled code test within this bug. [Risks and why]: Low, because the change only affects the CSP parser. [String/UUID change made/needed]: no
Attachment #8776140 - Flags: approval-mozilla-aurora?
Comment on attachment 8776342 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src.patch See comment 9.
Attachment #8776342 - Flags: approval-mozilla-aurora?
Comment on attachment 8776140 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src_tests.patch Sec issue, early in Beta49 cycle, taking it.
Attachment #8776140 - Flags: approval-mozilla-aurora? → approval-mozilla-beta+
Attachment #8776342 - Flags: approval-mozilla-aurora? → approval-mozilla-beta+
Christoph, given that ESR45 is affected, should we consider uplifting this to ESR45 branch as well? If so, please nominate patches for ESR45 uplift.
Flags: needinfo?(ckerschb)
has conflicts uplifting to beta: Tomcats-MacBook-Pro-2:mozilla-central Tomcat$ hg graft --edit -r b7dc3515dc78 grafting 357014:b7dc3515dc78 "Bug 1289085: CSP - Bail early if referrer directive has no valid src. r=dveditz" merging dom/security/nsCSPParser.cpp merging dom/security/nsCSPParser.h warning: conflicts while merging dom/security/nsCSPParser.cpp! (edit, then use 'hg resolve --mark') abort: unresolved conflicts, can't continue (use 'hg resolve' and 'hg graft --continue')
Group: dom-core-security → core-security-release
Comment on attachment 8776140 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src_tests.patch See comment 9.
Flags: needinfo?(ckerschb)
Attachment #8776140 - Flags: approval-mozilla-esr45?
Comment on attachment 8776342 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src.patch See comment 9.
Attachment #8776342 - Flags: approval-mozilla-esr45?
(In reply to Carsten Book [:Tomcat] from comment #13) > has conflicts uplifting to beta: Hey Carsten, I rebased the main patch for beta; the tests apply cleanly for beta. Let me know if that still doesn't work for whatever reason. Thanks!
Flags: needinfo?(cbook)
(In reply to Christoph Kerschbaumer [:ckerschb] from comment #16) > Created attachment 8779311 [details] [diff] [review] > bug_1289085_rebased_for_beta.patch > > (In reply to Carsten Book [:Tomcat] from comment #13) > > has conflicts uplifting to beta: > > Hey Carsten, I rebased the main patch for beta; the tests apply cleanly for > beta. Let me know if that still doesn't work for whatever reason. Thanks! thanks! worked perfect! landed in https://hg.mozilla.org/releases/mozilla-beta/rev/adadc9dbb648
Flags: needinfo?(cbook)
Comment on attachment 8776140 [details] [diff] [review] bug_1289085_csp_referrer_directive_with_no_valid_src_tests.patch doesn't match the esr criteria (sec-high / sec-critical), not taking it
Attachment #8776140 - Flags: approval-mozilla-esr45? → approval-mozilla-esr45-
Attachment #8776342 - Flags: approval-mozilla-esr45? → approval-mozilla-esr45-
Whiteboard: [domsecurity-active] → [domsecurity-active][adv-main49+]
Alias: CVE-2016-2827
Reproduced the original crash using the STR and the POC from comment #0. Once I reproduced the crash, went through the following verification process: Builds Used: * fx51.0a1 asan, buildId: 20160908150519 * fx50.0a2 asan, buildId: 20160909072720 * fx49.0b11 asan, buildId: 20160909092719 Platform Used: * Ubuntu 16.04.1 LTS VM Test Cases Used: * ensured that the original issue wasn't occuring using the STR from comment #0 * opened the poc in several regular tabs/windows and ensured fx didn't crash * opened the poc in several container tabs/windows and ensured fx didn't crash * opened the poc in several non-e10s tabs/windows and ensured fx didn't crash * opened the poc in several PB tabs/windows and ensured fx didn't crash
Status: RESOLVED → VERIFIED
Summary: Heap-buffer-overflow in mozilla::net::IsValidReferrerPolicy → Out-of-bounds read in mozilla::net::IsValidReferrerPolicy
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: