Skip to content

fix: nil pointer dereference in BlockStore.PruneBlocks when block is nil #2772

@rootulp

Description

@rootulp

Summary

BlockStore.PruneBlocks panics with a nil pointer dereference when LoadBlock() returns nil but LoadBlockMeta() returns non-nil.

Bug Location

store/store.go lines 403-409 (in v0.39.23)

Root Cause

meta := bs.LoadBlockMeta(h)
block := bs.LoadBlock(h)
if meta == nil { // assume already deleted
    continue
}

for _, tx := range block.Txs {  // PANIC: block can be nil even when meta is not!

The code checks if meta == nil but does not check if block == nil.

Looking at LoadBlock(), it can return nil even when LoadBlockMeta() returns non-nil:

func (bs *BlockStore) LoadBlock(height int64) *types.Block {
    blockMeta := bs.LoadBlockMeta(height)
    if blockMeta == nil {
        return nil
    }
    ...
    part := bs.LoadBlockPart(height, i)
    // If the part is missing we consider the whole block to be missing.
    if part == nil {
        return nil  // <-- Returns nil even if meta exists!
    }

This can happen when block parts are missing (e.g., deleted by a previous pruning operation) while metadata still exists.

Stack Trace

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x170 pc=0x1c85345]

goroutine 373 [running]:
github.com/cometbft/cometbft/store.(*BlockStore).PruneBlocks(...)
        store/store.go:409 +0x425
github.com/cometbft/cometbft/state.(*BlockExecutor).pruneBlocks(...)
        state/execution.go:921 +0x99
github.com/cometbft/cometbft/state.(*BlockExecutor).applyBlock(...)
        state/execution.go:420 +0x13c5
github.com/cometbft/cometbft/state.(*BlockExecutor).ApplyVerifiedBlock(...)
        state/execution.go:289
github.com/cometbft/cometbft/blocksync.(*Reactor).poolRoutine(...)
        blocksync/reactor.go:613 +0x17b5

Fix

 meta := bs.LoadBlockMeta(h)
 block := bs.LoadBlock(h)
-if meta == nil { // assume already deleted
+if meta == nil || block == nil { // assume already deleted
     continue
 }

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions