Operational Defect Database

BugZero found this defect 62 days ago.

MongoDB | 2612320

BinData bit comparisons give wrong results in many cases

Last update date:

3/18/2024

Affected products:

MongoDB Server

Affected releases:

5.3.2

4.3.6

3.6.23

4.0.28

5.1.1

6.1.1

5.2.1

6.2.1

4.2.25

6.3.2

7.1.1

5.0.25

Fixed releases:

No fixed releases provided.

Description:

Info

This reproduces for me in today's latest master branch, both with Classic engine and SBE. This is a server bug. It was injected in version 3.1.6 on 2015-07-15 by SERVER-19385 "Optimize Bit Test Query Operators with Numbers". This change introduced at least two bugs: It treats everything as a sign-extended 64-bit integer, so it skips checking for bit positions > 63. It converts BinData bit masks into a vector of integer bit positions incorrectly. Bug number 2 explains the behavior in the reproduction in the first comment below. The code comments say the lowest-order bit of the entire mask is bit position 0, but the implementation actually records the lowest order bit of the leftmost byte of the bit mask as bit position 0. The leftmost byte thus contains bit positions 0-7 right to left, the second byte contains bit positions 8-15 right to left, etc. In the repro data, the query uses the same BinData as the document with _id: 1. The docs that should match are 1, 3, 4 but only 1, 4 are actually retrieved. This is because of the bit mask swizzling bug: Should match _id Description _bitMask # bytes Desired _bitPositions Actual _bitPositions Yes 1 1n 11 80 0 2 1n 13 100 4 Yes 3 1n 13 80, 100 4, 16 Yes 4 1n 11 80, 85 0, 5 We see that _ids 1, 3, 4 should all have bit position 80 set and thus all be retrieved, but in the code they have wrong bit positions as described above and shown in the right-most column of the table. _ids 1 and 4 both have bit position 0 set, so they match, but _id3, which should match, does not have any bit positions set in common with _id 1, so it does not match and is not returned. It appears that bit tests using BinData bit masks (either data or probes) wider than 64 bits will not work correctly. Also, even when

Top User Comments

JIRAUSER1270811 commented on Mon, 18 Mar 2024 21:03:11 +0000: Reproduction Setup db.bitSet.drop(); let bdata1 = BinData(0, "AQAAAAAAAAAAAAA="); print("bdata1", bdata1, bdata1.length()); db.bitSet.insertOne({_id: 1, description: "1n << 80n", binaryValueofA: "0000000100000000000000000000000000000000000000000000000000000000000000000000000000000000", a: bdata1}); let bdata2 = BinData(0, "EAAAAAAAAAAAAAAAAA=="); print("bdata2", bdata2, bdata2.length()); db.bitSet.insertOne({_id: 2, description: "1n << 100n", binaryValueofA: "00010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", a: bdata2}); let bdata3 = BinData(0, "EAABAAAAAAAAAAAAAA=="); print("bdata3", bdata3, bdata3.length()); db.bitSet.insertOne({_id: 3, description: "1n << 80n | 1n << 100n", binaryValueofA: "00010000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000", a: bdata3}); let bdata4 = BinData(0, "IQAAAAAAAAAAAAA="); print("bdata4", bdata4, bdata4.length()); db.bitSet.insertOne({_id: 4, description: "1n << 80n | 1n << 85n", binaryValueofA: "0010000100000000000000000000000000000000000000000000000000000000000000000000000000000000", a: bdata4}); Query db.bitSet.find({a: {$bitsAnySet: BinData(0, "AQAAAAAAAAAAAAA=")}}); Expected results { "_id" : 1, "description" : "1n << 80n", "binaryValueofA" : "0000000100000000000000000000000000000000000000000000000000000000000000000000000000000000", "a" : BinData(0,"AQAAAAAAAAAAAAA=") } { "_id" : 3, "description" : "1n << 80n | 1n << 100n", "binaryValueofA" : "00010000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000", "a" : BinData(0,"EAABAAAAAAAAAAAAAA==") } { "_id" : 4, "description" : "1n << 80n | 1n << 85n", "binaryValueofA" : "0010000100000000000000000000000000000000000000000000000000000000000000000000000000000000", "a" : BinData(0,"IQAAAAAAAAAAAAA=") } Actual results (_id: 3 is missing) { "_id" : 1, "description" : "1n << 80n", "binaryValueofA" : "0000000100000000000000000000000000000000000000000000000000000000000000000000000000000000", "a" : BinData(0,"AQAAAAAAAAAAAAA=") } { "_id" : 4, "description" : "1n << 80n | 1n << 85n", "binaryValueofA" : "0010000100000000000000000000000000000000000000000000000000000000000000000000000000000000", "a" : BinData(0,"IQAAAAAAAAAAAAA=") }

Steps to Reproduce


Additional Resources / Links

Share:

BugZero® Risk Score

What's this?

Coming soon

Status

Needs Scheduling

Learn More

Search:

...