User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:126.96.36.199) 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.
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
8 years ago
blocking2.0: --- → beta9+
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.
Should this just be marked INVALID?
I wouldn't mind making this code more resilient against future changes.
blocking2.0: beta9+ → -
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Two possible buffer overflows in txNodeSet::ensureGrowSize → future-proof allocations in txNodeSet::ensureGrowSize
You need to log in before you can comment on or make changes to this bug.