[SERVER-73534] Serialization of 'sbe::TypeTags::ArraySet' to 'KeyString' can segfault Created: 01/Feb/23  Updated: 29/Oct/23  Resolved: 03/Feb/23

Status: Closed
Project: Core Server
Component/s: Query Execution
Affects Version/s: None
Fix Version/s: 6.3.0-rc0, 6.0.5

Type: Bug Priority: Major - P3
Reporter: David Storch Assignee: David Storch
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Backports
Depends
Related
related to SERVER-61629 Serialize sbe::value::Array[Set] and ... Backlog
Backwards Compatibility: Fully Compatible
Operating System: ALL
Backport Requested:
v6.0
Sprint: QE 2023-02-06
Participants:
Linked BF Score: 164

 Description   

This code is incorrect:

https://github.com/mongodb/mongo/blob/e536ab12f0be25b42983aaf492fa5eefc4cf8ce0/src/mongo/db/exec/sbe/values/slot.cpp#L456-L465

In the case that the input tag indicates that the value is type Array, everything works as expected. When the value is an ArraySet, however, this code leads to undefined behavior. I've seen it consistently crash the server with a segfault in practice.

The problem is that it calls getArrayView() on a value of type Array. This ends up interpreting the value as a pointer to an Array object when the value's actual runtime type is ArraySet. As soon as we try to access a data member of the pointed-to object, which happens here, we crash.

The buggy function is used for spilling to disk in SBE's HashAggStage and HashLookupStage. Therefore, the crash can happen if we ever decide to spill an entry in the hash table whose key contains a value of type ArraySet. This is a somewhat unusual situation, since it requires the following:

  1. A $group or $lookup that needs to spill at runtime.
  2. The $group or $lookup must be pushed down to SBE.
  3. The query must be such that an ArraySet becomes a key in the hash table. This is presumably an unusual use of MQL's set arithmetic operators.

This is a latent issue that was discovered our generational agg fuzzer. It was exposed due to the changes from SERVER-70395, but I believe that it affects all 6.0.x and 6.2.x versions. The reason we found it is that SERVER-70395 made a change to artificially increase the likelihood of spilling in debug builds. For this reason, as soon as SERVER-70395 was merged we started seeing the fuzzer cause this crash on debug builds only.



 Comments   
Comment by Githook User [ 06/Feb/23 ]

Author:

{'name': 'David Storch', 'email': 'david.storch@mongodb.com', 'username': 'dstorch'}

Message: SERVER-73534 Fix crash in serialization of SBE ArraySet to KeyString

(cherry picked from commit 7d633d3c72a5cffb8889632e5cfb545002514ebb)
Branch: v6.0
https://github.com/mongodb/mongo/commit/a002b8db7c521b553a9c5a4ad806af83754c7b55

Comment by Githook User [ 03/Feb/23 ]

Author:

{'name': 'David Storch', 'email': 'david.storch@mongodb.com', 'username': 'dstorch'}

Message: SERVER-73534 Fix crash in serialization of SBE ArraySet to KeyString
Branch: master
https://github.com/mongodb/mongo/commit/7d633d3c72a5cffb8889632e5cfb545002514ebb

Generated at Thu Feb 08 06:24:56 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.