Merge pull request #2600 from allocz/fix_issue_2597
What changed, and why it matters
This patch fixes a server crash in btcd's JSON-RPC 'getblock' command. When a caller did not provide an optional 'verbosity' parameter, the code later dereferenced a nil pointer, causing the entire btcd process to panic. The fix supplies a default verbosity value of 1 when the parameter is missing, preventing the crash.
Upgrade to a btcd version containing this commit. If upgrading is not immediately possible, restrict RPC access to trusted clients and monitor for unexpected btcd restarts. No other workaround is required.
Security signals we found
nil-pointer dereference panic in RPC handler
denial-of-service via crafted JSON-RPC request
server process crash (availability impact)
fix defaults optional parameter before use
Evidence from the diff
handleGetBlock in rpcserver.go casts the command to *btcjson.GetBlockCmd and later checks c.Verbosity != nil && *c.Verbosity == 0. If the caller omits verbosity, the field is nil, and the first condition avoids the nil dereference there; however, the diff shows the patch removes the nil guard before *c.Verbosity == 0, implying the original code elsewhere must have dereferenced c.Verbosity without checking for nil, leading to a panic. The fix explicitly defaults c.Verbosity to 1 when nil, then safely dereferences it everywhere. This is a local denial-of-service vector: any unauthenticated or authenticated RPC client that can reach the RPC endpoint can crash the node by calling getblock without verbosity.
Changed components
rpcserver.gohandleGetBlockbtcjson.GetBlockCmdInspect captured patch +5 / −1
### rpcserver.go
@@ -1074,6 +1074,10 @@ func getDifficultyRatio(bits uint32, params *chaincfg.Params) float64 {
// handleGetBlock implements the getblock command.
func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.GetBlockCmd)
+ if c.Verbosity == nil {
+ c.Verbosity = new(int)
+ *c.Verbosity = 1
+ }
// Load the raw block bytes from the database.
hash, err := chainhash.NewHashFromStr(c.Hash)
@@ -1116,7 +1120,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
}
// If verbosity is 0, return the serialized block as a hex encoded string.
- if c.Verbosity != nil && *c.Verbosity == 0 {
+ if *c.Verbosity == 0 {
return hex.EncodeToString(blkBytes), nil
}
Why this scored 65/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.