future-proof allocations in txNodeSet::ensureGrowSize

NEW
Assigned to

Status

()

8 years ago
7 years ago

People

(Reporter: alexander.miller, Assigned: sicking)

Tracking

({sec-other})

unspecified
x86
Linux
sec-other
Points:
---

Firefox Tracking Flags

(blocking2.0 -)

Details

(Whiteboard: [sg:nse], URL)

(Reporter)

Description

8 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12
Build Identifier: 

Provided the target's system has enough memory, two possible integer overflows resulting in incorrect allocation are possible at:

http://mxr.mozilla.org/mozilla-central/source/content/xslt/src/xpath/txNodeSet.cpp#553

(The developer even acknowledged memory safety hazards there)

http://mxr.mozilla.org/mozilla-central/source/content/xslt/src/xpath/txNodeSet.cpp#527

When overflown there, it is possible to trick the program in to thinking it has space to put the node, and if it doesn't node data overwrites adjacent memory.

Reproducible: Didn't try




In the IRC I was discussing this with bz, and because of the way operator new[] is compiled, this should only be exploitable on builds that were built with gcc, so at least for now, I'm marking this as Linux only.

Updated

8 years ago
Depends on: 466445

Comment 1

8 years ago
We're doing the multiplication-by-sizeof outselves here, so this isn't the gcc bug.
No longer depends on: 466445
Jonas, can you have a look here?
Assignee: nobody → jonas
blocking2.0: --- → beta9+
(Reporter)

Updated

8 years ago
Whiteboard: [sg:critical]
(Reporter)

Updated

8 years ago
Whiteboard: [sg:critical]
This doesn't look exploitable to me.

(Math below for 32bit)

In order for this allocation to overflow |newLength * sizeof(txXPathNode)| needs to be bigger than 2^32. In order for that to be the case we need newLength to be
greater than 2^32/8 = 2^29. Since we use a growing factor of 2, this means that we have to be growing a nodeset which is 2^28 in size.

Since nodesets always contain unique nodes, this means that we have to have 2^28 nodes. However the smallest node that I see is an empty textnode which in 1.9.2 is 6 words = 24 bytes large. These nodes also need to live in a child-list, meaning an extra 4 bytes per node is needed there.

This means that we'll need to have 28*2^28 = 1.75 * 2^32 bytes of node data. This is more than what fits in a 32bit process.

The math works out the same way on 64bit, just with bigger numbers.


You could try to create 2^27 nodes, and create two nodesets which contain them all and then merge those two nodesets. In that case we pessimistically allocate for 2^28 node slots and we would overflow.

Howevever even 2^27 nodes plus the two nodesets is enough that we'd run out of memory first.
(Reporter)

Comment 5

8 years ago
Should this just be marked INVALID?
I wouldn't mind making this code more resilient against future changes.
Not blocking.
blocking2.0: beta9+ → -
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Two possible buffer overflows in txNodeSet::ensureGrowSize → future-proof allocations in txNodeSet::ensureGrowSize
Whiteboard: [sg:nse]
Group: core-security
You need to log in before you can comment on or make changes to this bug.