Closed Bug 1709952 Opened 3 years ago Closed 3 years ago

Potential OBR parsing malicious ODoH configs

Categories

(Core :: Networking: DNS, defect, P2)

defect

Tracking

()

RESOLVED FIXED
90 Branch
Tracking Status
firefox-esr78 --- unaffected
firefox88 --- disabled
firefox89 --- disabled
firefox90 --- fixed

People

(Reporter: dveditz, Assigned: kershaw)

Details

(Keywords: csectype-bounds, sec-moderate, Whiteboard: [necko-triaged][post-critsmash-triage])

Attachments

(1 file)

The parsing of ODoH config files was switched from a raw buffer to a Span<T> in bug 1698015. This is good because Span<> has built-in Rust-like bounds checking, but the parser uses DNSParser's get16bit() which does not. There are a couple of places where the buffer length is checked to make sure there's more data, but a buffer that gives its size correctly as having enough length for the length data, but not enough for a full structure will end up reading garbage bytes during the while (length > 0) loop.

Likely saving us from easy exploitation is that length is unsigned, so when you keep decrementing it will underflow. Undefined so an optimizer might do something crazy, but usually wraps around into a huge number and the loop will keep going until it gets an access violation, or eventually the garbage its reading has a length interpreted as bigger than what we think is left.

without thinking too hard I think changing the while condition to be bigger than the size of the fixed part of the config structure would do it. There's a version in here, though. Will we try to support different versions, with potentially different sizes, in the future? that could complicate it a bit. In that case maybe more checking of length along the way: we have to know length is big enough before decrementing it at each step, or in sections where we decrement in a row of known sizes.

    while (length > 12) {

I Don't care for magic values like 12 so if the structures are actually defined somewhere (I assume so?) you could do some kind of sizeof(). But then your size could include compiler-added padding. Not sure that would happen with such simple structures, but maybe safer to just use a commented #define

If length != 0 at the end of the loop then there's bogus extra data. Not sure if that's worth logging. You log an invalid config, but not when you take the early return false bailouts so I leave that up to you.

I saw this because I happened to notice bug 1698015 (summary mentioned downloading configs) so I looked at that patch. I have not had time to look more widely at the code in this file but it's probably worth checking for similar patterns.

We don't check for overflow on index, either, but since it's the same uint16 as length that should be fine as long as we keep length from wrapping.

Summary: Potential OOR parsing malicious ODoH configs → Potential OBR parsing malicious ODoH configs

If you're going to use Span you should take advantage of it's Rust-like safety and let it do the indexing. If instead of get16bit(aData.Elements(), index) you did get16bit(aData[index], 0) it would be safer. That could still read one byte too far so get16bit(aData.FromTo(index, index+2), 0) would be better. If you want it prettier you could create a version of get16bit() that takes a Span explicitly and hides the repeating arguments.

If you do that the MOZ_RELEASE_ASSERT() bounds checks will trigger. You still have to fix the length checking in the loop also, but at least it would be memory-safe if people muck with this in the future and mess that part up.

Kershaw, can you take a look?

Flags: needinfo?(kershaw)
Assignee: nobody → kershaw
Severity: -- → S4
Flags: needinfo?(kershaw)
Priority: -- → P2
Whiteboard: [necko-triaged]
Group: network-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 90 Branch
Flags: qe-verify-
Whiteboard: [necko-triaged] → [necko-triaged][post-critsmash-triage]
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: