VYPR
Unrated severityNVD Advisory· Published Nov 23, 2020· Updated Sep 16, 2024

Invariant in IndexBoundsBuilder

CVE-2019-20924

Description

Authorized database users can cause a denial of service by issuing specially crafted queries that trigger an invariant in IndexBoundsBuilder, affecting MongoDB Server v4.2 before 4.2.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Authorized database users can cause a denial of service by issuing specially crafted queries that trigger an invariant in IndexBoundsBuilder, affecting MongoDB Server v4.2 before 4.2.2.

Vulnerability

A denial-of-service vulnerability exists in the IndexBoundsBuilder component of MongoDB Server versions 4.2.0 and 4.2.1, as well as 4.3.1 [1]. A user who is authorized to perform database queries can trigger an invariant failure by issuing specially crafted queries, causing the mongod process to crash [1]. The affected versions are MongoDB Server v4.2 prior to 4.2.2, and version 4.3.1 of the development branch [1].

Exploitation

An attacker must have valid authentication credentials and be authorized to issue database queries against the MongoDB server [1]. No additional privileges are required beyond normal query permissions. The attacker crafts and sends a malicious query that exploits the invariant in IndexBoundsBuilder. The query does not require user interaction from other parties and can be executed over the network [1].

Impact

Successful exploitation results in an invariant failure and subsequent crash of the mongod process, causing a denial of service (DoS) [1]. The confidentiality and integrity of the data are not affected; the impact is limited to availability. The authenticated attacker can repeatedly crash the server, disrupting normal operations [1].

Mitigation

The vulnerability is fixed in MongoDB Server version 4.2.2, released on November 24, 2019 [1]. Users should upgrade to 4.2.2 or later. For the affected development version 4.3.1, upgrading to a later 4.3.x release or to the stable 4.2 branch is recommended. There is no documented workaround for this issue [1].

AI Insight generated on May 26, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2
  • MongoDB/Serverllm-fuzzy
    Range: <4.2.2
  • MongoDB Inc./MongoDB Serverv5
    Range: 4.2

Patches

1
a0bbbff6ada1

Import wiredtiger: 8b63de583201b15f38cc161298d5ebc215c817a3 from branch mongodb-4.2

https://github.com/mongodb/mongoLuke ChenDec 4, 2019via osv
18 files changed · +180 220
  • src/third_party/wiredtiger/import.data+1 1 modified
    @@ -1,5 +1,5 @@
     {
    -    "commit": "1311372125d14fe97b07d0f4c165b1ad9efb4e9a", 
    +    "commit": "8b63de583201b15f38cc161298d5ebc215c817a3", 
         "github": "wiredtiger/wiredtiger.git", 
         "vendor": "wiredtiger", 
         "branch": "mongodb-4.2"
    
  • src/third_party/wiredtiger/src/btree/bt_curnext.c+4 8 modified
    @@ -159,7 +159,7 @@ __cursor_var_append_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                     ++cbt->page_deleted_count;
                 continue;
             }
    -        return (__wt_value_return(cbt, upd));
    +        return (__wt_value_return(session, cbt, upd));
         }
         /* NOTREACHED */
     }
    @@ -228,7 +228,7 @@ __cursor_var_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                         ++cbt->page_deleted_count;
                     continue;
                 }
    -            return (__wt_value_return(cbt, upd));
    +            return (__wt_value_return(session, cbt, upd));
             }
     
             /*
    @@ -351,7 +351,7 @@ __cursor_row_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                 }
                 key->data = WT_INSERT_KEY(ins);
                 key->size = WT_INSERT_KEY_SIZE(ins);
    -            return (__wt_value_return(cbt, upd));
    +            return (__wt_value_return(session, cbt, upd));
             }
     
             /* Check for the end of the page. */
    @@ -481,12 +481,8 @@ __wt_cursor_key_order_check(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, bool
      *     Initialize key ordering checks for cursor movements after a successful search.
      */
     int
    -__wt_cursor_key_order_init(WT_CURSOR_BTREE *cbt)
    +__wt_cursor_key_order_init(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
     {
    -    WT_SESSION_IMPL *session;
    -
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
    -
         /*
          * Cursor searches set the position for cursor movements, set the last-key value for diagnostic
          * checking.
    
  • src/third_party/wiredtiger/src/btree/bt_curprev.c+3 3 modified
    @@ -300,7 +300,7 @@ __cursor_var_append_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                     ++cbt->page_deleted_count;
                 continue;
             }
    -        return (__wt_value_return(cbt, upd));
    +        return (__wt_value_return(session, cbt, upd));
         }
         /* NOTREACHED */
     }
    @@ -370,7 +370,7 @@ __cursor_var_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                         ++cbt->page_deleted_count;
                     continue;
                 }
    -            return (__wt_value_return(cbt, upd));
    +            return (__wt_value_return(session, cbt, upd));
             }
     
             /*
    @@ -502,7 +502,7 @@ __cursor_row_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
                 }
                 key->data = WT_INSERT_KEY(ins);
                 key->size = WT_INSERT_KEY_SIZE(ins);
    -            return (__wt_value_return(cbt, upd));
    +            return (__wt_value_return(session, cbt, upd));
             }
     
             /* Check for the beginning of the page. */
    
  • src/third_party/wiredtiger/src/btree/bt_cursor.c+70 83 modified
    @@ -367,14 +367,11 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *valid)
      *     Column-store search from a cursor.
      */
     static inline int
    -__cursor_col_search(WT_CURSOR_BTREE *cbt, WT_REF *leaf, bool *leaf_foundp)
    +__cursor_col_search(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_REF *leaf)
     {
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
    -    WT_WITH_PAGE_INDEX(
    -      session, ret = __wt_col_search(cbt, cbt->iface.recno, leaf, false, leaf_foundp));
    +    WT_WITH_PAGE_INDEX(session, ret = __wt_col_search(session, cbt->iface.recno, leaf, cbt, false));
         return (ret);
     }
     
    @@ -383,14 +380,12 @@ __cursor_col_search(WT_CURSOR_BTREE *cbt, WT_REF *leaf, bool *leaf_foundp)
      *     Row-store search from a cursor.
      */
     static inline int
    -__cursor_row_search(WT_CURSOR_BTREE *cbt, bool insert, WT_REF *leaf, bool *leaf_foundp)
    +__cursor_row_search(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_REF *leaf, bool insert)
     {
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         WT_WITH_PAGE_INDEX(
    -      session, ret = __wt_row_search(cbt, &cbt->iface.key, insert, leaf, false, leaf_foundp));
    +      session, ret = __wt_row_search(session, &cbt->iface.key, leaf, cbt, insert, false));
         return (ret);
     }
     
    @@ -399,39 +394,43 @@ __cursor_row_search(WT_CURSOR_BTREE *cbt, bool insert, WT_REF *leaf, bool *leaf_
      *     Column-store modify from a cursor, with a separate value.
      */
     static inline int
    -__cursor_col_modify_v(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
    +__cursor_col_modify_v(
    +  WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
     {
    -    return (__wt_col_modify(cbt, cbt->iface.recno, value, NULL, modify_type, false));
    +    return (__wt_col_modify(session, cbt, cbt->iface.recno, value, NULL, modify_type, false));
     }
     
     /*
      * __cursor_row_modify_v --
      *     Row-store modify from a cursor, with a separate value.
      */
     static inline int
    -__cursor_row_modify_v(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
    +__cursor_row_modify_v(
    +  WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
     {
    -    return (__wt_row_modify(cbt, &cbt->iface.key, value, NULL, modify_type, false));
    +    return (__wt_row_modify(session, cbt, &cbt->iface.key, value, NULL, modify_type, false));
     }
     
     /*
      * __cursor_col_modify --
      *     Column-store modify from a cursor.
      */
     static inline int
    -__cursor_col_modify(WT_CURSOR_BTREE *cbt, u_int modify_type)
    +__cursor_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, u_int modify_type)
     {
    -    return (__wt_col_modify(cbt, cbt->iface.recno, &cbt->iface.value, NULL, modify_type, false));
    +    return (
    +      __wt_col_modify(session, cbt, cbt->iface.recno, &cbt->iface.value, NULL, modify_type, false));
     }
     
     /*
      * __cursor_row_modify --
      *     Row-store modify from a cursor.
      */
     static inline int
    -__cursor_row_modify(WT_CURSOR_BTREE *cbt, u_int modify_type)
    +__cursor_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, u_int modify_type)
     {
    -    return (__wt_row_modify(cbt, &cbt->iface.key, &cbt->iface.value, NULL, modify_type, false));
    +    return (
    +      __wt_row_modify(session, cbt, &cbt->iface.key, &cbt->iface.value, NULL, modify_type, false));
     }
     
     /*
    @@ -485,8 +484,8 @@ __wt_btcur_search_uncommitted(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp)
         session = (WT_SESSION_IMPL *)cursor->session;
         *updp = upd = NULL; /* -Wuninitialized */
     
    -    WT_RET(btree->type == BTREE_ROW ? __cursor_row_search(cbt, false, NULL, NULL) :
    -                                      __cursor_col_search(cbt, NULL, NULL));
    +    WT_RET(btree->type == BTREE_ROW ? __cursor_row_search(session, cbt, NULL, false) :
    +                                      __cursor_col_search(session, cbt, NULL));
     
         /*
          * Ideally exact match should be found, as this transaction has searched for updates done by
    @@ -525,7 +524,7 @@ __wt_btcur_search(WT_CURSOR_BTREE *cbt)
         WT_DECL_RET;
         WT_SESSION_IMPL *session;
         WT_UPDATE *upd;
    -    bool leaf_found, valid;
    +    bool valid;
     
         btree = cbt->btree;
         cursor = &cbt->iface;
    @@ -556,26 +555,26 @@ __wt_btcur_search(WT_CURSOR_BTREE *cbt)
         if (__cursor_page_pinned(cbt, true)) {
             __wt_txn_cursor_op(session);
     
    -        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, false, cbt->ref, &leaf_found) :
    -                                          __cursor_col_search(cbt, cbt->ref, &leaf_found));
    +        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(session, cbt, cbt->ref, false) :
    +                                          __cursor_col_search(session, cbt, cbt->ref));
     
             /* Return, if prepare conflict encountered. */
    -        if (leaf_found && cbt->compare == 0)
    +        if (cbt->compare == 0)
                 WT_ERR(__wt_cursor_valid(cbt, &upd, &valid));
         }
         if (!valid) {
             WT_ERR(__cursor_func_init(cbt, true));
     
    -        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, false, NULL, NULL) :
    -                                          __cursor_col_search(cbt, NULL, NULL));
    +        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(session, cbt, NULL, false) :
    +                                          __cursor_col_search(session, cbt, NULL));
     
             /* Return, if prepare conflict encountered. */
             if (cbt->compare == 0)
                 WT_ERR(__wt_cursor_valid(cbt, &upd, &valid));
         }
     
         if (valid)
    -        ret = __cursor_kv_return(cbt, upd);
    +        ret = __cursor_kv_return(session, cbt, upd);
         else if (__cursor_fix_implicit(btree, cbt)) {
             /*
              * Creating a record past the end of the tree in a fixed-length column-store implicitly
    @@ -592,7 +591,7 @@ __wt_btcur_search(WT_CURSOR_BTREE *cbt)
     
     #ifdef HAVE_DIAGNOSTIC
         if (ret == 0)
    -        WT_ERR(__wt_cursor_key_order_init(cbt));
    +        WT_ERR(__wt_cursor_key_order_init(session, cbt));
     #endif
     
     err:
    @@ -617,7 +616,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
         WT_SESSION_IMPL *session;
         WT_UPDATE *upd;
         int exact;
    -    bool leaf_found, valid;
    +    bool valid;
     
         btree = cbt->btree;
         cursor = &cbt->iface;
    @@ -655,7 +654,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
         if (btree->type == BTREE_ROW && __cursor_page_pinned(cbt, true)) {
             __wt_txn_cursor_op(session);
     
    -        WT_ERR(__cursor_row_search(cbt, true, cbt->ref, &leaf_found));
    +        WT_ERR(__cursor_row_search(session, cbt, cbt->ref, true));
     
             /*
              * Search-near is trickier than search when searching an already pinned page. If search
    @@ -664,13 +663,13 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
              * append lists (there may be no page slots or we might be legitimately positioned after the
              * last page slot). Ignore those cases, it makes things too complicated.
              */
    -        if (leaf_found && cbt->slot != 0 && cbt->slot != cbt->ref->page->entries - 1)
    +        if (cbt->slot != 0 && cbt->slot != cbt->ref->page->entries - 1)
                 WT_ERR(__wt_cursor_valid(cbt, &upd, &valid));
         }
         if (!valid) {
             WT_ERR(__cursor_func_init(cbt, true));
    -        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, true, NULL, NULL) :
    -                                          __cursor_col_search(cbt, NULL, NULL));
    +        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(session, cbt, NULL, true) :
    +                                          __cursor_col_search(session, cbt, NULL));
             WT_ERR(__wt_cursor_valid(cbt, &upd, &valid));
         }
     
    @@ -691,7 +690,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
          */
         if (valid) {
             exact = cbt->compare;
    -        ret = __cursor_kv_return(cbt, upd);
    +        ret = __cursor_kv_return(session, cbt, upd);
         } else if (__cursor_fix_implicit(btree, cbt)) {
             cbt->recno = cursor->recno;
             cbt->v = 0;
    @@ -737,7 +736,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
     
     #ifdef HAVE_DIAGNOSTIC
         if (ret == 0)
    -        WT_TRET(__wt_cursor_key_order_init(cbt));
    +        WT_TRET(__wt_cursor_key_order_init(session, cbt));
     #endif
     
         if (ret != 0) {
    @@ -807,8 +806,8 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
              * Correct to an exact match so we can update whatever we're pointing at.
              */
             cbt->compare = 0;
    -        ret = btree->type == BTREE_ROW ? __cursor_row_modify(cbt, WT_UPDATE_STANDARD) :
    -                                         __cursor_col_modify(cbt, WT_UPDATE_STANDARD);
    +        ret = btree->type == BTREE_ROW ? __cursor_row_modify(session, cbt, WT_UPDATE_STANDARD) :
    +                                         __cursor_col_modify(session, cbt, WT_UPDATE_STANDARD);
             if (ret == 0)
                 goto done;
     
    @@ -835,7 +834,7 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
         WT_ERR(__cursor_func_init(cbt, true));
     
         if (btree->type == BTREE_ROW) {
    -        WT_ERR(__cursor_row_search(cbt, true, NULL, NULL));
    +        WT_ERR(__cursor_row_search(session, cbt, NULL, true));
             /*
              * If not overwriting, fail if the key exists, else insert the key/value pair.
              */
    @@ -845,19 +844,19 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
                     WT_ERR(WT_DUPLICATE_KEY);
             }
     
    -        ret = __cursor_row_modify(cbt, WT_UPDATE_STANDARD);
    +        ret = __cursor_row_modify(session, cbt, WT_UPDATE_STANDARD);
         } else if (append_key) {
             /*
              * Optionally insert a new record (ignoring the application's record number). The real
              * record number is allocated by the serialized append operation.
              */
             cbt->iface.recno = WT_RECNO_OOB;
             cbt->compare = 1;
    -        WT_ERR(__cursor_col_search(cbt, NULL, NULL));
    -        WT_ERR(__cursor_col_modify(cbt, WT_UPDATE_STANDARD));
    +        WT_ERR(__cursor_col_search(session, cbt, NULL));
    +        WT_ERR(__cursor_col_modify(session, cbt, WT_UPDATE_STANDARD));
             cursor->recno = cbt->recno;
         } else {
    -        WT_ERR(__cursor_col_search(cbt, NULL, NULL));
    +        WT_ERR(__cursor_col_search(session, cbt, NULL));
     
             /*
              * If not overwriting, fail if the key exists. Creating a record past the end of the tree in
    @@ -873,7 +872,7 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
                     WT_ERR(WT_DUPLICATE_KEY);
             }
     
    -        WT_ERR(__cursor_col_modify(cbt, WT_UPDATE_STANDARD));
    +        WT_ERR(__cursor_col_modify(session, cbt, WT_UPDATE_STANDARD));
         }
     
     err:
    @@ -953,7 +952,7 @@ __wt_btcur_insert_check(WT_CURSOR_BTREE *cbt)
     
     retry:
         WT_ERR(__cursor_func_init(cbt, true));
    -    WT_ERR(__cursor_row_search(cbt, true, NULL, NULL));
    +    WT_ERR(__cursor_row_search(session, cbt, NULL, true));
     
         /* Just check for conflicts. */
         ret = __curfile_update_check(cbt);
    @@ -1028,8 +1027,8 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
              * Correct to an exact match so we can remove whatever we're pointing at.
              */
             cbt->compare = 0;
    -        ret = btree->type == BTREE_ROW ? __cursor_row_modify(cbt, WT_UPDATE_TOMBSTONE) :
    -                                         __cursor_col_modify(cbt, WT_UPDATE_TOMBSTONE);
    +        ret = btree->type == BTREE_ROW ? __cursor_row_modify(session, cbt, WT_UPDATE_TOMBSTONE) :
    +                                         __cursor_col_modify(session, cbt, WT_UPDATE_TOMBSTONE);
             if (ret == 0)
                 goto done;
             goto err;
    @@ -1050,7 +1049,7 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
         WT_ERR(__cursor_func_init(cbt, true));
     
         if (btree->type == BTREE_ROW) {
    -        ret = __cursor_row_search(cbt, false, NULL, NULL);
    +        ret = __cursor_row_search(session, cbt, NULL, false);
             if (ret == WT_NOTFOUND)
                 goto search_notfound;
             WT_ERR(ret);
    @@ -1064,9 +1063,9 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
             if (!valid)
                 goto search_notfound;
     
    -        ret = __cursor_row_modify(cbt, WT_UPDATE_TOMBSTONE);
    +        ret = __cursor_row_modify(session, cbt, WT_UPDATE_TOMBSTONE);
         } else {
    -        ret = __cursor_col_search(cbt, NULL, NULL);
    +        ret = __cursor_col_search(session, cbt, NULL);
             if (ret == WT_NOTFOUND)
                 goto search_notfound;
             WT_ERR(ret);
    @@ -1094,7 +1093,7 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
                  */
                 cbt->recno = cursor->recno;
             } else
    -            ret = __cursor_col_modify(cbt, WT_UPDATE_TOMBSTONE);
    +            ret = __cursor_col_modify(session, cbt, WT_UPDATE_TOMBSTONE);
         }
     
     err:
    @@ -1112,7 +1111,7 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
              */
             if (positioned) {
                 if (searched)
    -                WT_TRET(__wt_key_return(cbt));
    +                WT_TRET(__wt_key_return(session, cbt));
             } else {
                 F_CLR(cursor, WT_CURSTD_KEY_SET);
                 WT_TRET(__cursor_reset(cbt));
    @@ -1175,7 +1174,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
         WT_DECL_RET;
         WT_SESSION_IMPL *session;
         uint64_t yield_count, sleep_usecs;
    -    bool leaf_found, valid;
    +    bool valid;
     
         btree = cbt->btree;
         cursor = &cbt->iface;
    @@ -1204,8 +1203,8 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
              * Correct to an exact match so we can update whatever we're pointing at.
              */
             cbt->compare = 0;
    -        ret = btree->type == BTREE_ROW ? __cursor_row_modify_v(cbt, value, modify_type) :
    -                                         __cursor_col_modify_v(cbt, value, modify_type);
    +        ret = btree->type == BTREE_ROW ? __cursor_row_modify_v(session, cbt, value, modify_type) :
    +                                         __cursor_col_modify_v(session, cbt, value, modify_type);
             if (ret == 0)
                 goto done;
     
    @@ -1228,22 +1227,12 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
         WT_ERR(__cursor_localvalue(cursor));
         __cursor_state_save(cursor, &state);
     
    -    /* If our caller configures for a local search and we have a page pinned, do that search. */
    -    if (F_ISSET(cursor, WT_CURSTD_UPDATE_LOCAL) && __cursor_page_pinned(cbt, true)) {
    -        __wt_txn_cursor_op(session);
    -
    -        WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, true, cbt->ref, &leaf_found) :
    -                                          __cursor_col_search(cbt, cbt->ref, &leaf_found));
    -        if (leaf_found)
    -            goto update_local;
    -    }
    -
     retry:
         WT_ERR(__cursor_func_init(cbt, true));
    -    WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, true, NULL, NULL) :
    -                                      __cursor_col_search(cbt, NULL, NULL));
    -update_local:
    +
         if (btree->type == BTREE_ROW) {
    +        WT_ERR(__cursor_row_search(session, cbt, NULL, true));
    +
             /*
              * If not overwriting, check for conflicts and fail if the key does not exist.
              */
    @@ -1255,8 +1244,10 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
                 if (!valid)
                     WT_ERR(WT_NOTFOUND);
             }
    -        ret = __cursor_row_modify_v(cbt, value, modify_type);
    +        ret = __cursor_row_modify_v(session, cbt, value, modify_type);
         } else {
    +        WT_ERR(__cursor_col_search(session, cbt, NULL));
    +
             /*
              * If not overwriting, fail if the key doesn't exist. If we find an update for the key,
              * check for conflicts. Update the record if it exists. Creating a record past the end of
    @@ -1271,7 +1262,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
                 if ((cbt->compare != 0 || !valid) && !__cursor_fix_implicit(btree, cbt))
                     WT_ERR(WT_NOTFOUND);
             }
    -        ret = __cursor_col_modify_v(cbt, value, modify_type);
    +        ret = __cursor_col_modify_v(session, cbt, value, modify_type);
         }
     
     err:
    @@ -1294,7 +1285,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
                 /*
                  * WT_CURSOR.update returns a key and a value.
                  */
    -            ret = __cursor_kv_return(cbt, cbt->modify_update);
    +            ret = __cursor_kv_return(session, cbt, cbt->modify_update);
                 break;
             case WT_UPDATE_RESERVE:
                 /*
    @@ -1307,7 +1298,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
                  * WT_CURSOR.modify has already created the return value and our job is to leave it
                  * untouched.
                  */
    -            ret = __wt_key_return(cbt);
    +            ret = __wt_key_return(session, cbt);
                 break;
             case WT_UPDATE_BIRTHMARK:
             case WT_UPDATE_TOMBSTONE:
    @@ -1631,14 +1622,12 @@ __wt_btcur_equals(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *equalp)
      *     Discard a cursor range from row-store or variable-width column-store tree.
      */
     static int
    -__cursor_truncate(
    -  WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop, int (*rmfunc)(WT_CURSOR_BTREE *, u_int))
    +__cursor_truncate(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
    +  int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, u_int))
     {
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
         uint64_t yield_count, sleep_usecs;
     
    -    session = (WT_SESSION_IMPL *)start->iface.session;
         yield_count = sleep_usecs = 0;
     
     /*
    @@ -1661,7 +1650,7 @@ __cursor_truncate(
         WT_ASSERT(session, F_MASK((WT_CURSOR *)start, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
     
         for (;;) {
    -        WT_ERR(rmfunc(start, WT_UPDATE_TOMBSTONE));
    +        WT_ERR(rmfunc(session, start, WT_UPDATE_TOMBSTONE));
     
             if (stop != NULL && __cursor_equals(start, stop))
                 return (0);
    @@ -1686,15 +1675,13 @@ __cursor_truncate(
      *     Discard a cursor range from fixed-width column-store tree.
      */
     static int
    -__cursor_truncate_fix(
    -  WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop, int (*rmfunc)(WT_CURSOR_BTREE *, u_int))
    +__cursor_truncate_fix(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
    +  int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, u_int))
     {
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
         uint64_t yield_count, sleep_usecs;
         const uint8_t *value;
     
    -    session = (WT_SESSION_IMPL *)start->iface.session;
         yield_count = sleep_usecs = 0;
     
     /*
    @@ -1720,7 +1707,7 @@ __cursor_truncate_fix(
         for (;;) {
             value = (const uint8_t *)start->iface.value.data;
             if (*value != 0)
    -            WT_ERR(rmfunc(start, WT_UPDATE_TOMBSTONE));
    +            WT_ERR(rmfunc(session, start, WT_UPDATE_TOMBSTONE));
     
             if (stop != NULL && __cursor_equals(start, stop))
                 return (0);
    @@ -1768,10 +1755,10 @@ __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop)
     
         switch (btree->type) {
         case BTREE_COL_FIX:
    -        WT_ERR(__cursor_truncate_fix(start, stop, __cursor_col_modify));
    +        WT_ERR(__cursor_truncate_fix(session, start, stop, __cursor_col_modify));
             break;
         case BTREE_COL_VAR:
    -        WT_ERR(__cursor_truncate(start, stop, __cursor_col_modify));
    +        WT_ERR(__cursor_truncate(session, start, stop, __cursor_col_modify));
             break;
         case BTREE_ROW:
             /*
    @@ -1783,7 +1770,7 @@ __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop)
              * setting up the truncate so we're good to go: if that ever changes, we'd need to do
              * something here to ensure a fully instantiated cursor.
              */
    -        WT_ERR(__cursor_truncate(start, stop, __cursor_row_modify));
    +        WT_ERR(__cursor_truncate(session, start, stop, __cursor_row_modify));
             break;
         }
     
    
  • src/third_party/wiredtiger/src/btree/bt_random.c+22 33 modified
    @@ -55,14 +55,12 @@ __random_slot_valid(WT_CURSOR_BTREE *cbt, uint32_t slot, WT_UPDATE **updp, bool
      *     Return an estimate of how many entries are in a skip list.
      */
     static uint32_t
    -__random_skip_entries(WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head)
    +__random_skip_entries(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head)
     {
         WT_INSERT **t;
    -    WT_SESSION_IMPL *session;
         uint32_t entries;
         int level;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         entries = 0; /* [-Wconditional-uninitialized] */
     
         if (ins_head == NULL)
    @@ -104,19 +102,16 @@ __random_skip_entries(WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head)
      *     Return a random key/value from a skip list.
      */
     static int
    -__random_leaf_skip(
    -  WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head, uint32_t entries, WT_UPDATE **updp, bool *validp)
    +__random_leaf_skip(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head,
    +  uint32_t entries, WT_UPDATE **updp, bool *validp)
     {
         WT_INSERT *ins, *saved_ins;
    -    WT_SESSION_IMPL *session;
         uint32_t i;
         int retry;
     
         *updp = NULL;
         *validp = false;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
    -
         /* This is a relatively expensive test, try a few times then quit. */
         for (retry = 0; retry < WT_RANDOM_SKIP_RETRY; ++retry) {
             /*
    @@ -164,24 +159,22 @@ __random_leaf_skip(
      *     Look for a large insert list from which we can select a random item.
      */
     static int
    -__random_leaf_insert(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
    +__random_leaf_insert(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
     {
         WT_INSERT_HEAD *ins_head;
         WT_PAGE *page;
    -    WT_SESSION_IMPL *session;
         uint32_t entries, slot, start;
     
         *updp = NULL;
         *validp = false;
     
         page = cbt->ref->page;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
     
         /* Check for a large insert list with no items, that's common when tables are newly created. */
         ins_head = WT_ROW_INSERT_SMALLEST(page);
    -    entries = __random_skip_entries(cbt, ins_head);
    +    entries = __random_skip_entries(session, cbt, ins_head);
         if (entries >= WT_RANDOM_SKIP_INSERT_SMALLEST_ENOUGH) {
    -        WT_RET(__random_leaf_skip(cbt, ins_head, entries, updp, validp));
    +        WT_RET(__random_leaf_skip(session, cbt, ins_head, entries, updp, validp));
             if (*validp)
                 return (0);
         }
    @@ -195,18 +188,18 @@ __random_leaf_insert(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
             start = __wt_random(&session->rnd) % page->entries;
             for (slot = start; slot < page->entries; ++slot) {
                 ins_head = WT_ROW_INSERT(page, &page->pg_row[slot]);
    -            entries = __random_skip_entries(cbt, ins_head);
    +            entries = __random_skip_entries(session, cbt, ins_head);
                 if (entries >= WT_RANDOM_SKIP_INSERT_ENOUGH) {
    -                WT_RET(__random_leaf_skip(cbt, ins_head, entries, updp, validp));
    +                WT_RET(__random_leaf_skip(session, cbt, ins_head, entries, updp, validp));
                     if (*validp)
                         return (0);
                 }
             }
             for (slot = 0; slot < start; ++slot) {
                 ins_head = WT_ROW_INSERT(page, &page->pg_row[slot]);
    -            entries = __random_skip_entries(cbt, ins_head);
    +            entries = __random_skip_entries(session, cbt, ins_head);
                 if (entries >= WT_RANDOM_SKIP_INSERT_ENOUGH) {
    -                WT_RET(__random_leaf_skip(cbt, ins_head, entries, updp, validp));
    +                WT_RET(__random_leaf_skip(session, cbt, ins_head, entries, updp, validp));
                     if (*validp)
                         return (0);
                 }
    @@ -215,9 +208,9 @@ __random_leaf_insert(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
     
         /* Fall back to the single insert list, if it's not tiny. */
         ins_head = WT_ROW_INSERT_SMALLEST(page);
    -    entries = __random_skip_entries(cbt, ins_head);
    +    entries = __random_skip_entries(session, cbt, ins_head);
         if (entries >= WT_RANDOM_SKIP_INSERT_ENOUGH) {
    -        WT_RET(__random_leaf_skip(cbt, ins_head, entries, updp, validp));
    +        WT_RET(__random_leaf_skip(session, cbt, ins_head, entries, updp, validp));
             if (*validp)
                 return (0);
         }
    @@ -232,18 +225,16 @@ __random_leaf_insert(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
      *     Return a random key/value from a page's on-disk entries.
      */
     static int
    -__random_leaf_disk(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
    +__random_leaf_disk(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
     {
         WT_PAGE *page;
    -    WT_SESSION_IMPL *session;
         uint32_t entries, slot;
         int retry;
     
         *updp = NULL;
         *validp = false;
     
         page = cbt->ref->page;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         entries = cbt->ref->page->entries;
     
         /* This is a relatively cheap test, so try several times. */
    @@ -269,42 +260,40 @@ __random_leaf_disk(WT_CURSOR_BTREE *cbt, WT_UPDATE **updp, bool *validp)
      *     Return a random key/value from a row-store leaf page.
      */
     static int
    -__random_leaf(WT_CURSOR_BTREE *cbt)
    +__random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
     {
         WT_CURSOR *cursor;
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
         WT_UPDATE *upd;
         uint32_t i;
         bool next, valid;
     
         cursor = (WT_CURSOR *)cbt;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
     
         /*
          * If the page has a sufficiently large number of disk-based entries, randomly select from them.
          * Ignoring large insert lists could skew the results, but enough disk-based entries should span
          * a reasonable chunk of the name space.
          */
         if (cbt->ref->page->entries > WT_RANDOM_DISK_ENOUGH) {
    -        WT_RET(__random_leaf_disk(cbt, &upd, &valid));
    +        WT_RET(__random_leaf_disk(session, cbt, &upd, &valid));
             if (valid)
    -            return (__cursor_kv_return(cbt, upd));
    +            return (__cursor_kv_return(session, cbt, upd));
         }
     
         /* Look for any large insert list and select from it. */
    -    WT_RET(__random_leaf_insert(cbt, &upd, &valid));
    +    WT_RET(__random_leaf_insert(session, cbt, &upd, &valid));
         if (valid)
    -        return (__cursor_kv_return(cbt, upd));
    +        return (__cursor_kv_return(session, cbt, upd));
     
         /*
          * Try again if there are at least a few hundred disk-based entries: this may be a normal leaf
          * page with big items.
          */
         if (cbt->ref->page->entries > WT_RANDOM_DISK_ENOUGH / 2) {
    -        WT_RET(__random_leaf_disk(cbt, &upd, &valid));
    +        WT_RET(__random_leaf_disk(session, cbt, &upd, &valid));
             if (valid)
    -            return (__cursor_kv_return(cbt, upd));
    +            return (__cursor_kv_return(session, cbt, upd));
         }
     
         /*
    @@ -519,7 +508,7 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt)
             WT_ERR(__cursor_func_init(cbt, true));
             WT_WITH_PAGE_INDEX(session, ret = __wt_random_descent(session, &cbt->ref, read_flags));
             if (ret == 0) {
    -            WT_ERR(__random_leaf(cbt));
    +            WT_ERR(__random_leaf(session, cbt));
                 return (0);
             }
     
    @@ -593,7 +582,7 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt)
             WT_ERR(__wt_btcur_next(cbt, false));
     
         /* Select a random entry from the leaf page. */
    -    WT_ERR(__random_leaf(cbt));
    +    WT_ERR(__random_leaf(session, cbt));
     
         return (0);
     
    
  • src/third_party/wiredtiger/src/btree/bt_read.c+4 4 modified
    @@ -31,8 +31,8 @@ __col_instantiate(
             __wt_free_update_list(session, upd);
     
         /* Search the page and add updates. */
    -    WT_RET(__wt_col_search(cbt, recno, ref, true, NULL));
    -    WT_RET(__wt_col_modify(cbt, recno, NULL, updlist, WT_UPDATE_INVALID, false));
    +    WT_RET(__wt_col_search(session, recno, ref, cbt, true));
    +    WT_RET(__wt_col_modify(session, cbt, recno, NULL, updlist, WT_UPDATE_INVALID, false));
         return (0);
     }
     
    @@ -59,8 +59,8 @@ __row_instantiate(
             __wt_free_update_list(session, upd);
     
         /* Search the page and add updates. */
    -    WT_RET(__wt_row_search(cbt, key, true, ref, true, NULL));
    -    WT_RET(__wt_row_modify(cbt, key, NULL, updlist, WT_UPDATE_INVALID, false));
    +    WT_RET(__wt_row_search(session, key, ref, cbt, true, true));
    +    WT_RET(__wt_row_modify(session, cbt, key, NULL, updlist, WT_UPDATE_INVALID, false));
         return (0);
     }
     
    
  • src/third_party/wiredtiger/src/btree/bt_ret.c+10 15 modified
    @@ -13,17 +13,15 @@
      *     Change the cursor to reference an internal return key.
      */
     static inline int
    -__key_return(WT_CURSOR_BTREE *cbt)
    +__key_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
     {
         WT_CURSOR *cursor;
         WT_ITEM *tmp;
         WT_PAGE *page;
         WT_ROW *rip;
    -    WT_SESSION_IMPL *session;
     
         page = cbt->ref->page;
         cursor = &cbt->iface;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
     
         if (page->type == WT_PAGE_ROW_LEAF) {
             rip = &page->pg_row[cbt->slot];
    @@ -74,18 +72,16 @@ __key_return(WT_CURSOR_BTREE *cbt)
      *     Change the cursor to reference an internal original-page return value.
      */
     static inline int
    -__value_return(WT_CURSOR_BTREE *cbt)
    +__value_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
     {
         WT_BTREE *btree;
         WT_CELL *cell;
         WT_CELL_UNPACK unpack;
         WT_CURSOR *cursor;
         WT_PAGE *page;
         WT_ROW *rip;
    -    WT_SESSION_IMPL *session;
         uint8_t v;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         btree = S2BT(session);
     
         page = cbt->ref->page;
    @@ -127,18 +123,17 @@ __value_return(WT_CURSOR_BTREE *cbt)
      *     Change the cursor to reference an internal update structure return value.
      */
     int
    -__wt_value_return_upd(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool ignore_visibility)
    +__wt_value_return_upd(
    +  WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool ignore_visibility)
     {
         WT_CURSOR *cursor;
         WT_DECL_RET;
    -    WT_SESSION_IMPL *session;
         WT_UPDATE **listp, *list[WT_MODIFY_ARRAY_SIZE];
         size_t allocated_bytes;
         u_int i;
         bool skipped_birthmark;
     
         cursor = &cbt->iface;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         allocated_bytes = 0;
     
         /*
    @@ -217,7 +212,7 @@ __wt_value_return_upd(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool ignore_visibili
                  */
                 WT_ASSERT(session, cbt->slot != UINT32_MAX);
     
    -            WT_ERR(__value_return(cbt));
    +            WT_ERR(__value_return(session, cbt));
             }
         } else if (upd->type == WT_UPDATE_TOMBSTONE)
             WT_ERR(__wt_buf_set(session, &cursor->value, "", 0));
    @@ -241,7 +236,7 @@ __wt_value_return_upd(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool ignore_visibili
      *     Change the cursor to reference an internal return key.
      */
     int
    -__wt_key_return(WT_CURSOR_BTREE *cbt)
    +__wt_key_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
     {
         WT_CURSOR *cursor;
     
    @@ -257,7 +252,7 @@ __wt_key_return(WT_CURSOR_BTREE *cbt)
          */
         F_CLR(cursor, WT_CURSTD_KEY_EXT);
         if (!F_ISSET(cursor, WT_CURSTD_KEY_INT)) {
    -        WT_RET(__key_return(cbt));
    +        WT_RET(__key_return(session, cbt));
             F_SET(cursor, WT_CURSTD_KEY_INT);
         }
         return (0);
    @@ -268,17 +263,17 @@ __wt_key_return(WT_CURSOR_BTREE *cbt)
      *     Change the cursor to reference an internal return value.
      */
     int
    -__wt_value_return(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
    +__wt_value_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
     {
         WT_CURSOR *cursor;
     
         cursor = &cbt->iface;
     
         F_CLR(cursor, WT_CURSTD_VALUE_EXT);
         if (upd == NULL)
    -        WT_RET(__value_return(cbt));
    +        WT_RET(__value_return(session, cbt));
         else
    -        WT_RET(__wt_value_return_upd(cbt, upd, false));
    +        WT_RET(__wt_value_return_upd(session, cbt, upd, false));
         F_SET(cursor, WT_CURSTD_VALUE_INT);
         return (0);
     }
    
  • src/third_party/wiredtiger/src/btree/bt_split.c+7 5 modified
    @@ -1445,10 +1445,10 @@ __split_multi_inmem(WT_SESSION_IMPL *session, WT_PAGE *orig, WT_MULTI *multi, WT
                 recno = WT_INSERT_RECNO(supd->ins);
     
                 /* Search the page. */
    -            WT_ERR(__wt_col_search(&cbt, recno, ref, true, NULL));
    +            WT_ERR(__wt_col_search(session, recno, ref, &cbt, true));
     
                 /* Apply the modification. */
    -            WT_ERR(__wt_col_modify(&cbt, recno, NULL, upd, WT_UPDATE_INVALID, true));
    +            WT_ERR(__wt_col_modify(session, &cbt, recno, NULL, upd, WT_UPDATE_INVALID, true));
                 break;
             case WT_PAGE_ROW_LEAF:
                 /* Build a key. */
    @@ -1467,13 +1467,15 @@ __split_multi_inmem(WT_SESSION_IMPL *session, WT_PAGE *orig, WT_MULTI *multi, WT
                 WT_ASSERT(session, __wt_count_birthmarks(upd) <= 1);
     
                 /* Search the page. */
    -            WT_ERR(__wt_row_search(&cbt, key, true, ref, true, NULL));
    +            WT_ERR(__wt_row_search(session, key, ref, &cbt, true, true));
     
    -            /* Birthmarks should only be applied to on-page values. */
    +            /*
    +             * Birthmarks should only be applied to on-page values.
    +             */
                 WT_ASSERT(session, cbt.compare == 0 || upd->type != WT_UPDATE_BIRTHMARK);
     
                 /* Apply the modification. */
    -            WT_ERR(__wt_row_modify(&cbt, key, NULL, upd, WT_UPDATE_INVALID, true));
    +            WT_ERR(__wt_row_modify(session, &cbt, key, NULL, upd, WT_UPDATE_INVALID, true));
                 break;
             default:
                 WT_ERR(__wt_illegal_value(session, orig->type));
    
  • src/third_party/wiredtiger/src/btree/col_modify.c+2 4 modified
    @@ -15,8 +15,8 @@ static int __col_insert_alloc(WT_SESSION_IMPL *, uint64_t, u_int, WT_INSERT **,
      *     Column-store delete, insert, and update.
      */
     int
    -__wt_col_modify(WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value, WT_UPDATE *upd_arg,
    -  u_int modify_type, bool exclusive)
    +__wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno,
    +  const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
     {
         static const WT_ITEM col_fix_remove = {"", 1, NULL, 0, 0};
         WT_BTREE *btree;
    @@ -25,7 +25,6 @@ __wt_col_modify(WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value, WT_U
         WT_INSERT_HEAD *ins_head, **ins_headp;
         WT_PAGE *page;
         WT_PAGE_MODIFY *mod;
    -    WT_SESSION_IMPL *session;
         WT_UPDATE *old_upd, *upd;
         size_t ins_size, upd_size;
         u_int i, skipdepth;
    @@ -34,7 +33,6 @@ __wt_col_modify(WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value, WT_U
         btree = cbt->btree;
         ins = NULL;
         page = cbt->ref->page;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         upd = upd_arg;
         append = logged = false;
     
    
  • src/third_party/wiredtiger/src/btree/col_srch.c+12 9 modified
    @@ -59,7 +59,7 @@ __check_leaf_key_range(WT_SESSION_IMPL *session, uint64_t recno, WT_REF *leaf, W
      */
     int
     __wt_col_search(
    -  WT_CURSOR_BTREE *cbt, uint64_t search_recno, WT_REF *leaf, bool leaf_safe, bool *leaf_foundp)
    +  WT_SESSION_IMPL *session, uint64_t search_recno, WT_REF *leaf, WT_CURSOR_BTREE *cbt, bool restore)
     {
         WT_BTREE *btree;
         WT_COL *cip;
    @@ -69,12 +69,10 @@ __wt_col_search(
         WT_PAGE *page;
         WT_PAGE_INDEX *pindex, *parent_pindex;
         WT_REF *current, *descent;
    -    WT_SESSION_IMPL *session;
         uint64_t recno;
         uint32_t base, indx, limit, read_flags;
         int depth;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         btree = S2BT(session);
         current = NULL;
     
    @@ -90,18 +88,23 @@ __wt_col_search(
         /*
          * We may be searching only a single leaf page, not the full tree. In the normal case where we
          * are searching a tree, check the page's parent keys before doing the full search, it's faster
    -     * when the cursor is being re-positioned. Skip that check if we know the page is the right one
    -     * (for example, when re-instantiating a page in memory, in that case we know the target must be
    -     * on the current page).
    +     * when the cursor is being re-positioned. Skip this if the page is being re-instantiated in
    +     * memory.
          */
         if (leaf != NULL) {
             WT_ASSERT(session, search_recno != WT_RECNO_OOB);
     
    -        if (!leaf_safe) {
    +        if (!restore) {
                 WT_RET(__check_leaf_key_range(session, recno, leaf, cbt));
    -            *leaf_foundp = cbt->compare == 0;
    -            if (!*leaf_foundp)
    +            if (cbt->compare != 0) {
    +                /*
    +                 * !!!
    +                 * WT_CURSOR.search_near uses the slot value to
    +                 * decide if there was an on-page match.
    +                 */
    +                cbt->slot = 0;
                     return (0);
    +            }
             }
     
             current = leaf;
    
  • src/third_party/wiredtiger/src/btree/row_modify.c+2 4 modified
    @@ -41,15 +41,14 @@ __wt_page_modify_alloc(WT_SESSION_IMPL *session, WT_PAGE *page)
      *     Row-store insert, update and delete.
      */
     int
    -__wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value, WT_UPDATE *upd_arg,
    -  u_int modify_type, bool exclusive)
    +__wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *key,
    +  const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
     {
         WT_DECL_RET;
         WT_INSERT *ins;
         WT_INSERT_HEAD *ins_head, **ins_headp;
         WT_PAGE *page;
         WT_PAGE_MODIFY *mod;
    -    WT_SESSION_IMPL *session;
         WT_UPDATE *old_upd, *upd, **upd_entry;
         size_t ins_size, upd_size;
         uint32_t ins_slot;
    @@ -58,7 +57,6 @@ __wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value,
     
         ins = NULL;
         page = cbt->ref->page;
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         upd = upd_arg;
         logged = false;
     
    
  • src/third_party/wiredtiger/src/btree/row_srch.c+13 10 modified
    @@ -206,8 +206,8 @@ __check_leaf_key_range(
      *     Search a row-store tree for a specific key.
      */
     int
    -__wt_row_search(WT_CURSOR_BTREE *cbt, WT_ITEM *srch_key, bool insert, WT_REF *leaf, bool leaf_safe,
    -  bool *leaf_foundp)
    +__wt_row_search(WT_SESSION_IMPL *session, WT_ITEM *srch_key, WT_REF *leaf, WT_CURSOR_BTREE *cbt,
    +  bool insert, bool restore)
     {
         WT_BTREE *btree;
         WT_COLLATOR *collator;
    @@ -218,13 +218,11 @@ __wt_row_search(WT_CURSOR_BTREE *cbt, WT_ITEM *srch_key, bool insert, WT_REF *le
         WT_PAGE_INDEX *pindex, *parent_pindex;
         WT_REF *current, *descent;
         WT_ROW *rip;
    -    WT_SESSION_IMPL *session;
         size_t match, skiphigh, skiplow;
         uint32_t base, indx, limit, read_flags;
         int cmp, depth;
         bool append_check, descend_right, done;
     
    -    session = (WT_SESSION_IMPL *)cbt->iface.session;
         btree = S2BT(session);
         collator = btree->collator;
         item = cbt->tmp;
    @@ -253,16 +251,21 @@ __wt_row_search(WT_CURSOR_BTREE *cbt, WT_ITEM *srch_key, bool insert, WT_REF *le
         /*
          * We may be searching only a single leaf page, not the full tree. In the normal case where we
          * are searching a tree, check the page's parent keys before doing the full search, it's faster
    -     * when the cursor is being re-positioned. Skip that check if we know the page is the right one
    -     * (for example, when re-instantiating a page in memory, in that case we know the target must be
    -     * on the current page).
    +     * when the cursor is being re-positioned. Skip this if the page is being re-instantiated in
    +     * memory.
          */
         if (leaf != NULL) {
    -        if (!leaf_safe) {
    +        if (!restore) {
                 WT_RET(__check_leaf_key_range(session, srch_key, leaf, cbt));
    -            *leaf_foundp = cbt->compare == 0;
    -            if (!*leaf_foundp)
    +            if (cbt->compare != 0) {
    +                /*
    +                 * !!!
    +                 * WT_CURSOR.search_near uses the slot value to
    +                 * decide if there was an on-page match.
    +                 */
    +                cbt->slot = 0;
                     return (0);
    +            }
             }
     
             current = leaf;
    
  • src/third_party/wiredtiger/src/cache/cache_las.c+2 9 modified
    @@ -646,9 +646,6 @@ __wt_las_insert_block(
         __las_set_isolation(session, &saved_isolation);
         local_txn = true;
     
    -    /* Inserts should be on the same page absent a split, search any pinned leaf page. */
    -    F_SET(cursor, WT_CURSTD_UPDATE_LOCAL);
    -
         /* Enter each update in the boundary's list into the lookaside store. */
         for (las_counter = 0, i = 0, list = multi->supd; i < multi->supd_entries; ++i, ++list) {
             /* Lookaside table key component: source key. */
    @@ -747,11 +744,8 @@ __wt_las_insert_block(
                     cursor->set_value(cursor, upd->txnid, upd->start_ts, upd->durable_ts,
                       upd->prepare_state, upd->type, &las_value);
     
    -            /*
    -             * Using update instead of insert so the page stays pinned and can be searched before
    -             * the tree.
    -             */
    -            WT_ERR(cursor->update(cursor));
    +            /* Using insert so we don't keep the page pinned longer than necessary. */
    +            WT_ERR(cursor->insert(cursor));
                 ++insert_cnt;
                 if (upd->prepare_state == WT_PREPARE_INPROGRESS)
                     ++prepared_insert_cnt;
    @@ -775,7 +769,6 @@ __wt_las_insert_block(
             else
                 WT_TRET(__wt_txn_rollback(session, NULL));
             __las_restore_isolation(session, saved_isolation);
    -        F_CLR(cursor, WT_CURSTD_UPDATE_LOCAL);
     
             /* Adjust the entry count. */
             if (ret == 0) {
    
  • src/third_party/wiredtiger/src/include/cursor.i+4 4 modified
    @@ -303,10 +303,10 @@ __wt_cursor_dhandle_decr_use(WT_SESSION_IMPL *session)
      *     Return a page referenced key/value pair to the application.
      */
     static inline int
    -__cursor_kv_return(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
    +__cursor_kv_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
     {
    -    WT_RET(__wt_key_return(cbt));
    -    WT_RET(__wt_value_return(cbt, upd));
    +    WT_RET(__wt_key_return(session, cbt));
    +    WT_RET(__wt_value_return(session, cbt, upd));
     
         return (0);
     }
    @@ -441,7 +441,7 @@ value:
          * (if any) is visible.
          */
         if (upd != NULL)
    -        return (__wt_value_return(cbt, upd));
    +        return (__wt_value_return(session, cbt, upd));
     
         /* Else, simple values have their location encoded in the WT_ROW. */
         if (__wt_row_leaf_value(page, rip, vb))
    
  • src/third_party/wiredtiger/src/include/extern.h+14 13 modified
    @@ -366,11 +366,11 @@ extern int __wt_clsm_open_bulk(WT_CURSOR_LSM *clsm, const char *cfg[])
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_clsm_request_switch(WT_CURSOR_LSM *clsm)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_col_modify(WT_CURSOR_BTREE *cbt, uint64_t recno, const WT_ITEM *value,
    -  WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
    +extern int __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno,
    +  const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_col_search(WT_CURSOR_BTREE *cbt, uint64_t search_recno, WT_REF *leaf,
    -  bool leaf_safe, bool *leaf_foundp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    +extern int __wt_col_search(WT_SESSION_IMPL *session, uint64_t search_recno, WT_REF *leaf,
    +  WT_CURSOR_BTREE *cbt, bool restore) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_collator_config(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM *cname,
       WT_CONFIG_ITEM *metadata, WT_COLLATOR **collatorp, int *ownp)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    @@ -532,7 +532,7 @@ extern int __wt_cursor_init(WT_CURSOR *cursor, const char *uri, WT_CURSOR *owner
       WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_cursor_key_order_check(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, bool next)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_cursor_key_order_init(WT_CURSOR_BTREE *cbt)
    +extern int __wt_cursor_key_order_init(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, bool key) WT_GCC_FUNC_DECL_ATTRIBUTE((cold))
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    @@ -752,7 +752,8 @@ extern int __wt_json_to_item(WT_SESSION_IMPL *session, const char *jstr, const c
     extern int __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype,
       const char **tokstart, size_t *toklen) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")))
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_key_return(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    +extern int __wt_key_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt)
    +  WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_las_config(WT_SESSION_IMPL *session, const char **cfg)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_las_create(WT_SESSION_IMPL *session, const char **cfg)
    @@ -1192,11 +1193,11 @@ extern int __wt_row_leaf_key_work(WT_SESSION_IMPL *session, WT_PAGE *page, WT_RO
       WT_ITEM *keyb, bool instantiate) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_row_leaf_keys(WT_SESSION_IMPL *session, WT_PAGE *page)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value,
    -  WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
    +extern int __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *key,
    +  const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type, bool exclusive)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_row_search(WT_CURSOR_BTREE *cbt, WT_ITEM *srch_key, bool insert, WT_REF *leaf,
    -  bool leaf_safe, bool *leaf_foundp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    +extern int __wt_row_search(WT_SESSION_IMPL *session, WT_ITEM *srch_key, WT_REF *leaf,
    +  WT_CURSOR_BTREE *cbt, bool insert, bool restore) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_rwlock_init(WT_SESSION_IMPL *session, WT_RWLOCK *l)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[])
    @@ -1490,10 +1491,10 @@ extern int __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value, WT_
       size_t *sizep, u_int modify_type) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_upgrade(WT_SESSION_IMPL *session, const char *cfg[])
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_value_return(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
    -  WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    -extern int __wt_value_return_upd(WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool ignore_visibility)
    +extern int __wt_value_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
    +extern int __wt_value_return_upd(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd,
    +  bool ignore_visibility) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[])
       WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
     extern int __wt_verbose_dump_cache(WT_SESSION_IMPL *session)
    
  • src/third_party/wiredtiger/src/include/wiredtiger.in+2 3 modified
    @@ -718,9 +718,8 @@ struct __wt_cursor {
     #define	WT_CURSTD_OVERWRITE	0x02000u
     #define	WT_CURSTD_RAW		0x04000u
     #define	WT_CURSTD_RAW_SEARCH	0x08000u
    -#define	WT_CURSTD_UPDATE_LOCAL	0x10000u
    -#define	WT_CURSTD_VALUE_EXT	0x20000u	/* Value points out of tree. */
    -#define	WT_CURSTD_VALUE_INT	0x40000u	/* Value points into tree. */
    +#define	WT_CURSTD_VALUE_EXT	0x10000u	/* Value points out of tree. */
    +#define	WT_CURSTD_VALUE_INT	0x20000u	/* Value points into tree. */
     /* AUTOMATIC FLAG VALUE GENERATION STOP */
     #define	WT_CURSTD_KEY_SET	(WT_CURSTD_KEY_EXT | WT_CURSTD_KEY_INT)
     #define	WT_CURSTD_VALUE_SET	(WT_CURSTD_VALUE_EXT | WT_CURSTD_VALUE_INT)
    
  • src/third_party/wiredtiger/src/reconcile/rec_col.c+5 5 modified
    @@ -606,14 +606,12 @@ __wt_rec_col_var(
     
         btree = S2BT(session);
         vpack = &_vpack;
    +    cbt = &r->update_modify_cbt;
         page = pageref->page;
         upd = NULL;
         size = 0;
         data = NULL;
     
    -    cbt = &r->update_modify_cbt;
    -    cbt->iface.session = (WT_SESSION *)session;
    -
         /*
          * Acquire the newest-durable timestamp for this page so we can roll it forward. If it exists,
          * it's in the WT_REF structure or the parent's disk image.
    @@ -774,7 +772,8 @@ __wt_rec_col_var(
                     switch (upd->type) {
                     case WT_UPDATE_MODIFY:
                         cbt->slot = WT_COL_SLOT(page, cip);
    -                    WT_ERR(__wt_value_return_upd(cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
    +                    WT_ERR(
    +                      __wt_value_return_upd(session, cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
                         data = cbt->iface.value.data;
                         size = (uint32_t)cbt->iface.value.size;
                         update_no_copy = false;
    @@ -1031,7 +1030,8 @@ __wt_rec_col_var(
                          * Impossible slot, there's no backing on-page item.
                          */
                         cbt->slot = UINT32_MAX;
    -                    WT_ERR(__wt_value_return_upd(cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
    +                    WT_ERR(
    +                      __wt_value_return_upd(session, cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
                         data = cbt->iface.value.data;
                         size = (uint32_t)cbt->iface.value.size;
                         update_no_copy = false;
    
  • src/third_party/wiredtiger/src/reconcile/rec_row.c+3 7 modified
    @@ -560,9 +560,7 @@ __rec_row_leaf_insert(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins)
         bool ovfl_key, upd_saved;
     
         btree = S2BT(session);
    -
         cbt = &r->update_modify_cbt;
    -    cbt->iface.session = (WT_SESSION *)session;
     
         key = &r->k;
         val = &r->v;
    @@ -603,7 +601,7 @@ __rec_row_leaf_insert(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins)
                  * Impossible slot, there's no backing on-page item.
                  */
                 cbt->slot = UINT32_MAX;
    -            WT_RET(__wt_value_return_upd(cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
    +            WT_RET(__wt_value_return_upd(session, cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
                 WT_RET(__wt_rec_cell_build_val(session, r, cbt->iface.value.data, cbt->iface.value.size,
                   start_ts, start_txn, stop_ts, stop_txn, 0));
                 break;
    @@ -689,12 +687,10 @@ __wt_rec_row_leaf(
         const void *p;
     
         btree = S2BT(session);
    +    cbt = &r->update_modify_cbt;
         page = pageref->page;
         slvg_skip = salvage == NULL ? 0 : salvage->skip;
     
    -    cbt = &r->update_modify_cbt;
    -    cbt->iface.session = (WT_SESSION *)session;
    -
         key = &r->k;
         val = &r->v;
         vpack = &_vpack;
    @@ -849,7 +845,7 @@ __wt_rec_row_leaf(
                 switch (upd->type) {
                 case WT_UPDATE_MODIFY:
                     cbt->slot = WT_ROW_SLOT(page, rip);
    -                WT_ERR(__wt_value_return_upd(cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
    +                WT_ERR(__wt_value_return_upd(session, cbt, upd, F_ISSET(r, WT_REC_VISIBLE_ALL)));
                     WT_ERR(__wt_rec_cell_build_val(session, r, cbt->iface.value.data,
                       cbt->iface.value.size, start_ts, start_txn, stop_ts, stop_txn, 0));
                     dictionary = true;
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

1

News mentions

0

No linked articles in our index yet.