[SERVER-13881] buffer overrun in BSONIteratorSorted in case of an invalid BSON object Created: 08/May/14  Updated: 06/Dec/22  Resolved: 10/Oct/22

Status: Closed
Project: Core Server
Component/s: Internal Code
Affects Version/s: None
Fix Version/s: features we're not sure of

Type: Bug Priority: Major - P3
Reporter: Bruce Lucas (Inactive) Assignee: Backlog - Storage Execution Team
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Storage Execution
Operating System: ALL
Participants:

 Description   

BSONIteratorSorted::BSONIteratorSorted() calls BSONObj::nFields() and allocates an array that size to hold the fields to be sorted. It then iterates over the fields using BSONObjIterator::more() to terminate the loop, whereas BSONObj::nFields() counts the fields by iterating using BSONObjIterator::moreWithEOO() and BSONElement::eoo() to terminate the loop. The net result is that if the object is invalid or damaged - for example, it has 0s where data is expected - nFields() can see a smaller number of elements than BSONIteratorSorted(), causing a buffer overrun in the _fields buffer in BSONIteratorSorted().

To reproduce on 2.4.10, start with a fresh db, insert an object, damage it, then try to update it:

    killall mongod
    rm -rf db db.log
    mkdir -p db
    mongod --dbpath db --smallfiles --oplogSize 50 --logpath db.log --fork
    mongo test --eval 'db.dropDatabase()'
    mongo test --eval 'db.c.insert({x:0, y:0, z:0}); db.getLastError()'
    mongo admin --eval 'db.shutdownServer()'
    dd if=/dev/zero of=db/test.0 bs=1 seek=$((0x20e0)) count=4 conv=notrunc # 2.4.10
    mongod --dbpath db --smallfiles --oplogSize 50 --logpath db.log --fork
    mongo --eval 'db.c.update({}, {$set: {y:0}}); db.getLastError()'
    grep Assertion db.log

This should trigger the verify( x == _nfields ) assertion at jsobj.cpp:1291 as a result of the buffer overrun.

This test case did not reproduce the issue on 2.6.1 (even after adjusting the offset of the dd above to account for the different extent layout), but the code in BSONIteratorSorted() and nFields() has not changed, so apparently still has the same issue, even if not triggered by this test case.



 Comments   
Comment by Geert Bosch [ 10/Oct/22 ]

We are closing this, as there should be no cases where we operate on damaged BSON data. On ingest, we validate structural integrity of BSON objects, and the database will not allow construction of incorrect BSON.

With the WiredTIger storage engine all data is uses checksum to ensure detection of on-disk corruption. As a final layer, we have the validate command to establish data validity for cases where there is suspicion that there still may be invalid BSON.

Generated at Thu Feb 08 03:33:11 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.