Skip to content

Release 0.9.2-2: memory-safety hardening + version bump - #686

Merged
DeckerSU merged 8 commits into
masterfrom
dev
Jun 24, 2026
Merged

DeckerSU merged 8 commits into
masterfrom
dev

Conversation

@DeckerSU

Copy link
Copy Markdown

Security fixes

Remote null-deref & use-after-free in block/script validation (#685)

  • IsCoinImport(): guard against empty data from a zero-length push opcode
    before reading data[0].
  • _DecodeHeirOpRet(): add empty() guard before reading vopret[0] on an
    empty OP_RETURN.
  • ConnectBlock(): reorder CCheckQueueControl after txdata so script-check
    threads are joined before txdata is destroyed — fixes a UAF on early return
    (CVE-2024-52911 class).

Harden CheckBlock & komodo_checkopret

  • CheckBlock(): zero-initialize pubkey33[33]; the December-hardfork branch
    read it unconditionally while it was only filled under fCheckPOW (UB).
  • komodo_checkopret(): guard empty vtx/vout before back().vout.back() to
    remove a latent out-of-bounds access.

Disable NSPV message processing

  • Refuse to start with -nspv_msg: the komodo_nSPVreq/komodo_nSPVresp P2P
    handlers do unsafe hand-rolled parsing of attacker-controlled payloads (stack
    overflow / OOB reads). AppInit2 now returns InitError, mirroring prune-mode
    rejection.

DeckerSU and others added 8 commits January 26, 2026 18:19
- Bump client version build number to 51
- Update copyright year to 2026
- Modify repository URL in AC_INIT for issue tracking
- Adjust KOMODO_VERSION to include a suffix for the new build
Three defensive fixes in consensus-reachable validation paths:

* CScript::IsCoinImport() (script/script.cpp): GetOp() can return true
  with empty data for a zero-length push opcode (e.g. OP_PUSHDATA1 0x00);
  the old code then read data.begin()[0]. Guard with !data.empty() and
  index via data[0]. Reachable while verifying a peer's transaction.

* _DecodeHeirOpRet() (cc/heir.cpp): the else-branch of
  _DecodeHeirEitherOpRet() can pass an empty vopret (OP_RETURN with no
  payload) into _DecodeHeirOpRet(), which read vopret.begin()[0] before
  any size check. Add an explicit empty() guard up front. Reachable
  during Heir CC validation.

* ConnectBlock() (main.cpp): CCheckQueueControl<CScriptCheck> control was
  declared before txdata. Since locals are destroyed in reverse order,
  txdata (held by reference from background script-check threads) was
  destroyed before control's destructor joined those threads -> UAF on
  early return (CVE-2024-52911 class). Move control's declaration after
  txdata so control is destroyed first while txdata is still alive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…_checkopret OOB

Two defensive fixes on the block-validation path:

* CheckBlock (main.cpp): pubkey33[33] was only filled by komodo_block2pubkey33()
  inside the `if (fCheckPOW)` branch, but the December-2019-hardfork branch reads
  it unconditionally via komodo_chosennotary(). On the normal AcceptBlock path
  CheckBlock is called with fCheckPOW=false and a real height > the hardfork, so
  pubkey33 was read uninitialized (UB). Zero-initialize it. Benign in practice
  (garbage practically never matches a notary key), but it is undefined behavior
  on every block.

* komodo_checkopret (komodo_bitcoind.cpp): read pblock->vtx.back().vout.back()
  with no emptiness checks; an empty vtx or empty vout in the last tx would
  dereference past the end. Add an explicit guard returning false. Reachability
  is gated by the notary branch above (so not a live remote crash), but this
  removes the latent out-of-bounds access.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…abled)

The getnSPV/nSPV P2P handlers (komodo_nSPVreq/komodo_nSPVresp) parse
attacker-controlled payloads with hand-rolled, insufficiently bounds-checked
byte indexing — a remotely memory-unsafe surface (stack buffer overflow in the
NSPV_UTXOS/NSPV_TXIDS coinaddr copy, out-of-bounds reads in NSPV_MEMPOOL and
others). It is off by default (DEFAULT_NSPV_PROCESSING=false), but could be
turned on with -nspv_msg.

Make it impossible to enable: AppInit2 now returns InitError when -nspv_msg is
set, mirroring how prune mode is rejected. Help text updated to note the mode is
unsupported.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
security: fix remote null-deref / use-after-free in block & script validation

Defensive hardening across consensus-reachable validation paths. Three commits:

  1. Remote null-deref & UAF in block/script validation (0ee75a6)
     - IsCoinImport(): guard against empty data from a zero-length push opcode
       before reading data[0] (reachable while verifying a peer's tx).
     - _DecodeHeirOpRet(): add empty() guard before reading vopret[0] on an
       empty OP_RETURN (reachable during Heir CC validation).
     - ConnectBlock(): reorder CCheckQueueControl after txdata so script-check
       threads are joined before txdata is destroyed — fixes a UAF on early
       return (CVE-2024-52911 class).
       
  2. Harden CheckBlock & komodo_checkopret (f6b0414)
     - CheckBlock(): zero-initialize pubkey33[33]; the December-hardfork branch
       read it unconditionally while it was only filled under fCheckPOW (UB).
     - komodo_checkopret(): guard empty vtx/vout before back().vout.back() to
       remove a latent out-of-bounds access.
       
  3. Disable NSPV message processing (b3eccc1)
     - Refuse to start with -nspv_msg: the komodo_nSPVreq/komodo_nSPVresp P2P
       handlers do unsafe hand-rolled parsing of attacker-controlled payloads
       (stack overflow / OOB reads). AppInit2 now returns InitError, mirroring
       prune-mode rejection.
- Bump _CLIENT_VERSION_BUILD / CLIENT_VERSION_BUILD from 51 to 52
- Update KOMODO_VERSION to 0.9.2-2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Turn off the osx-build job (if: false) and unwire it from the release
pipeline so Linux + Windows CD releases still publish:

- osx-build: if: false (kept in the file for easy re-enable)
- publish-release: drop osx-build from needs, remove the komodo-osx
  download step and the OSX release-asset upload step

Otherwise a skipped osx-build dependency would skip publish-release
entirely and no release would be produced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@DeckerSU
DeckerSU merged commit ae588a9 into master Jun 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant