Closed Bug 1568047 Opened 5 years ago Closed 5 years ago

IPC “bulk reading” a bool can cause undefined behavior

Categories

(Core :: IPC, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla70
Tracking Status
firefox-esr60 --- unaffected
firefox-esr68 --- fixed
firefox68 --- wontfix
firefox69 --- fixed
firefox70 --- fixed

People

(Reporter: tsmith, Assigned: jld)

References

(Blocks 2 open bugs, Regression)

Details

(4 keywords, Whiteboard: [adv-main69+][adv-esr68.1+][post-critsmash-triage])

Attachments

(2 files)

This issue has been hit by fuzzers in oss-fuzz and internal fuzzers.

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14986

/src/mozilla-central/netwerk/base/nsStandardURL.cpp:3426:29: runtime error: load of value 32, which is not a valid value for type 'const bool'
    #0 0x7f7ea52ffad4 in mozilla::net::nsStandardURL::Deserialize(mozilla::ipc::URIParams const&) mozilla-central/netwerk/base/nsStandardURL.cpp:3426:29
    #1 0x7f7ea50d95bc in BaseURIMutator<mozilla::net::nsStandardURL>::InitFromIPCParams(mozilla::ipc::URIParams const&) /work/obj-fuzz/dist/include/nsIURIMutator.h:69:21
    #2 0x7f7ea5a56da5 in mozilla::ipc::DeserializeURI(mozilla::ipc::URIParams const&) mozilla-central/ipc/glue/URIUtils.cpp:105:26
    #3 0x7f7ea8cfb4b6 in mozilla::dom::ContentParent::RecvPURLClassifierLocalConstructor(mozilla::dom::PURLClassifierLocalParent*, mozilla::ipc::URIParams const&, nsTArray<mozilla::dom::IPCURLClassifierFeature>&&) mozilla-central/dom/ipc/ContentParent.cpp:5587:26
    #4 0x7f7ea5be6181 in mozilla::dom::PContentParent::OnMessageReceived(IPC::Message const&) /work/obj-fuzz/ipc/ipdl/PContentParent.cpp:6692:57
    #5 0x7f7eab437f21 in void mozilla::ipc::FuzzProtocol<mozilla::dom::ContentParent>(mozilla::dom::ContentParent*, unsigned char const*, unsigned long, nsTArray<nsTString<char> > const&) /work/obj-fuzz/dist/include/ProtocolFuzzer.h:107:18
    #6 0x7f7eab437a2e in RunContentParentIPCFuzzing(unsigned char const*, unsigned long) mozilla-central/dom/ipc/fuzztest/content_parent_ipc_libfuzz.cpp:27:3
    #7 0x55d10cc6b94f in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)
    #8 0x55d10cc540ab in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long)
    #9 0x55d10cc56539 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long))
    #10 0x7f7eaac6573c in mozilla::FuzzerRunner::Run(int*, char***) mozilla-central/tools/fuzzing/interface/harness/FuzzerRunner.cpp:61:10
    #11 0x7f7eaabed551 in XREMain::XRE_mainStartup(bool*) mozilla-central/toolkit/xre/nsAppRunner.cpp:3819:35
    #12 0x7f7eaabf3c64 in XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&) mozilla-central/toolkit/xre/nsAppRunner.cpp:4771:12
    #13 0x7f7eaabf485d in XRE_main(int, char**, mozilla::BootstrapConfig const&) mozilla-central/toolkit/xre/nsAppRunner.cpp:4865:21
    #14 0x55d10cc11182 in do_main(int, char**, char**)
    #15 0x55d10cc10dce in main

The priority flag is not set for this bug.
:jimm, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(jmathies)

Jed, could you take a look at this one? Wondering what the priority should be.

Flags: needinfo?(jmathies) → needinfo?(jld)

The bad bool is being read from an IPDL-defined structure. The normal deserializer for bool handles unexpected values (by debug asserting and mapping them to true), but this isn't using the normal deserializer:

    if ((!((aMsg)->ReadBytesInto(aIter, (&((aVar)->supportsFileURL())), 1)))) {
        aActor->FatalError("Error bulk reading fields from bool");
        return false;
    }

The problem is on this line, from bug 1523996: bool is considered POD, which it is in the sense of having trivial ctors/dtor, but not in the sense that it's safe to copy arbitrary bits into it. I don't know if this is exploitable, but my understanding is that operating on a bool that isn't the representation of true or false is undefined behavior, and in particular I think I've seen examples where the compiler would take neither or both branches of an if statement. Depending on where and how we use vulnerable bools, this could potentially be a problem.

Group: dom-core-security
Component: DOM: Content Processes → IPC
Flags: needinfo?(jld)
Regressed by: 1523996
Summary: Use of uninitialized memory [@ mozilla::net::nsStandardURL::Deserialize] → IPC “bulk reading” a bool can cause undefined behavior
Keywords: regression
Attached file bools.txt

I did a simple text search looking for bool inside struct definitions in .ipdl and .ipdlh files, and there are a lot of them.

Attached file Bug 1568047.
Assignee: nobody → jld
Group: dom-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla70

ni? me to request uplift when it's been on m-c for a little longer

Flags: needinfo?(jld)

Comment on attachment 9084457 [details]
Bug 1568047.

Beta/Release Uplift Approval Request

  • User impact if declined: Exposure to possible security bugs (no concrete path to exploitation is currently known, but can't be ruled out).
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: Yes
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The effect of this change is larger than it looks due to autogenerated code, but IPC serialization is abstracted away so that other code won't be affected by changes in its details, and this just reverts us to the bool handling that we were using before 67 and still use in other contexts. It's been stable on Nightly for a week.
  • String changes made/needed: none

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: sec-moderate and relatively low risk
  • User impact if declined: Exposure to possible security bugs (no concrete path to exploitation is currently known, but can't be ruled out).
  • Fix Landed on Version: 70
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): (See above.)
  • String or UUID changes made by this patch: none
Flags: needinfo?(jld)
Attachment #9084457 - Flags: approval-mozilla-esr68?
Attachment #9084457 - Flags: approval-mozilla-beta?

Comment on attachment 9084457 [details]
Bug 1568047.

Fixes an IPC sec bug. Approved for 69.0b16 and 68.1esr.

Attachment #9084457 - Flags: approval-mozilla-esr68?
Attachment #9084457 - Flags: approval-mozilla-esr68+
Attachment #9084457 - Flags: approval-mozilla-beta?
Attachment #9084457 - Flags: approval-mozilla-beta+
Whiteboard: [adv-main69+][adv-esr68.1+]
Flags: qe-verify-
Whiteboard: [adv-main69+][adv-esr68.1+] → [adv-main69+][adv-esr68.1+][post-critsmash-triage]
Group: core-security-release
Has Regression Range: --- → yes
You need to log in before you can comment on or make changes to this bug.