[SERVER-12813] Overflow when converting double values in user input to long long values Created: 21/Feb/14  Updated: 08/Jan/24

Status: Open
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: 2.6.0-rc0
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Davide Italiano Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 0
Labels: 26qa, aggregation, grab-bag, query-44-grooming
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-35596 "max" field of the createCollection c... Closed
is related to SERVER-26148 Commands should convert integers from... Backlog
is related to SERVER-12814 Aggregation: cursor batchSize NaN is ... Backlog
is related to SERVER-25188 Add non-debug UBSan variant for jstes... Closed
Assigned Teams:
Query Optimization
Operating System: ALL
Participants:
Linked BF Score: 0

 Description   

If 'batchSize' argument in cursor exceeds some value, it overflows, being considered negative.

> use foo
switched to db foo
> var bigArray = [];
> for (var i = 0; i < 1000; ++i) { bigArray.push(i); }
1000
> var bigStr = Array(1001).toString();
> for (var i = 0; i < 100; ++i) { db.goo.insert({_id: i, bigArray: bigArray, bigStr: bigStr})};
WriteResult({ "nInserted" : 1 })
> var cursor = db.runCommand({aggregate: "goo", pipeline: [{$unwind:'$bigArray'}], cursor : {batchSize : Math.pow(2, 63)}})
> cursor
{
	"errmsg" : "exception: Cursor batchSize must not be negative",
	"code" : 16957,
	"ok" : 0
}
> var cursor = db.runCommand({aggregate: "goo", pipeline: [{$unwind:'$bigArray'}], cursor : {batchSize : Math.pow(2, 62)}})
> cursor
{
	"cursor" : {
		"id" : NumberLong(0),
		"ns" : "test.goo",
		"firstBatch" : [ ..... ] 
	},
	"ok" : 1
}

> print(Math.pow(2, 63))
9223372036854776000



 Comments   
Comment by Steve Tarzia [ 18/Jul/22 ]

Actually, nevermind, I need to reopen this because I tested again today locally on a master build (Linux/x86-64) and the bug is still there.  The recent test that passed on Atlas was on sandbox.ms2q3.mongodb.net.  Maybe that's an ARM graviton instance and the different CPU architectures are handling overflow or type conversion differently?

Comment by Steve Tarzia [ 15/Jul/22 ]

I tested on Altas with v5.0.8 and this bug is no longer present.  I don't know exactly when this was fixed, but it seems to be sometime between 4.4.0 and 5.0.8.

Comment by Charlie Swanson [ 13/Feb/17 ]

I can confirm this is still an issue. We still assume that addition can happen in any order, which is not technically correct.

Comment by Max Hirschhorn [ 05/Feb/16 ]

The Command::parseCommandCursorOptions() function uses BSONElement::numberLong() to convert the number to a long long. It is undefined behavior when the double value is larger than std::numeric_limits<long long>::max().

We should probably return an error the user in this situation rather than changing BSONElement::numberLong() to BSONElement::safeNumberLong() and treating the double value as std::numeric_limits<long long>::max(). However, rather than fixing this one place where we use BSONElement::numberLong(), we should audit the codebase for all other improper usages. For example, extracting the maxSize and maxObjects from the "dataSize" command.

Reassigning to the platform team's backlog.

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