Fix memory leak in __curhs_remove_int and __curhs_update when __wt_hs_modify fails

XMLWordPrintableJSON

    • Storage Engines, Storage Engines - Transactions
    • 49.846
    • SE Transactions - 2026-07-03
    • 1

      Problem

      Two history store cursor functions — _curhs_remove_int and curhs_update in src/cursor/cur_hs.c — use a retry loop around _wt_hs_modify to handle WT_RESTART:

      while ((ret = __wt_hs_modify(cbt, hs_tombstone)) == WT_RESTART) {
          WT_WITH_PAGE_INDEX(session, ret = __curhs_search(cbt, false));
          WT_ERR(ret);
      }
      // missing WT_ERR(ret) here
      

      If _wt_hs_modify returns a non-WT_RESTART error (e.g. OOM during wt_page_modify_init, or a write conflict from wt_txn_modify_check), the loop exits with ret != 0 but there is no WT_ERR(ret) to trigger the cleanup at err:. The allocated hs_tombstone (and hs_upd in _curhs_update) are leaked.

      The first history store insertion path (the do...while loop around line 1090) already uses the correct pattern:

      } while ((ret = __wt_hs_modify(cbt, hs_upd)) == WT_RESTART);
      WT_ERR(ret);
      

      Fix

      Add WT_ERR(ret) immediately after the closing brace of each while loop. The hs_tombstone = hs_upd = NULL assignment added after is purely defensive — since no fallible code follows the WT_ERR(ret) in either function, there is no actual double-free risk. The null assignment is kept to make the ownership transfer explicit to future readers and to match the established idiom in the file.

      Testing

      The fix was verified to compile cleanly across all build targets.

            Assignee:
            Chenhao Qu
            Reporter:
            Chenhao Qu
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: