Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-66389

segfault due to null JsFunction pointer for auto-parameterized $where

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Critical - P2 Critical - P2
    • 6.0.0-rc6, 6.1.0-rc0
    • Affects Version/s: 6.0.0-rc5, 6.1.0-rc0
    • Component/s: None
    • None
    • Fully Compatible
    • ALL
    • v6.0
    • QE 2022-05-16
    • 123

      When binding the value associated with an auto-parameterized $where MatchExpression node, we have a performance optimization to transfer ownership of the JsFunction rather than copying it. See the code here. The motivation for this optimization is that copying a JsFunction is very expensive, as it requires some kind of expensive initialization of the JavaScript engine.

      This optimization is not correct if there are multiple candidate plans. Imagine a scenario where there are two candidate plans. During preparation of the first candidate, we need to bind the JsFunction into the SBE runtime environment. The optimization kicks in, so we extract the JsFunction from the CanonicalQuery and pass ownership to the runtime environment. This leaves a nullptr in the $where node. For the second candidate plan, the optimization kicks in again. This time, the JsFunction pointer is null. The ownership transfer logic tolerates nullptr and is essentially a no-op this time around.

      Later, when we actually try to execute the second candidate plan's trial period, we assume that the JsFunction pointer is non-null and attempt to dereference it, resulting in a segmentation fault. This bug affects both master and the 6.0 branch.

      The easy way to fix this would be to revert the to optimization, and just copy the JsFunction into each candidate plan. (The implementation is a bit sketchy as is anyway, since it uses const_cast to discard the const qualifier.) The downside is that this approach have negative performance consequences. Another option would be to copy the JsFunction into all of the candidate plans except for the last one, or possibly to only have the optimization kick in when there is just one candidate plans. One other idea to look into is that we do clone the MatchExpression tree during plan enumeration – perhaps the JsFunction objects associated with each copy can be transferred to the corresponding SBE plans?

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:
              Resolved: