From 52b1d90f56faa96c8cec0adaba28a600f80da04b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 2 Mar 2021 14:46:48 +0400 Subject: [PATCH] rpc/jsonrpc: Unmarshal RPCRequest correctly (bp #6191) (#6193) * rpc/jsonrpc: Unmarshal RPCRequest correctly (#6191) i.e. without double pointer. With double pointer, it was possible to submit `null` value, which will crash the server. ``` panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x189ddc0] goroutine 1 [running]: github.com/tendermint/tendermint/rpc/jsonrpc/types.(*RPCRequest).UnmarshalJSON(0xc0000147e0, 0xc00029f201, 0x4, 0x1ff, 0x883baa0, 0xc0000147e0) /Users/anton/go/src/github.com/tendermint/tendermint/rpc/jsonrpc/types/types.go:70 +0x100 encoding/json.(*decodeState).literalStore(0xc000216bb0, 0xc00029f201, 0x4, 0x1ff, 0x1998800, 0xc0000147e0, 0x199, 0xc000231700, 0x10e0a5e, 0x197) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:860 +0x30ce encoding/json.(*decodeState).value(0xc000216bb0, 0x1998800, 0xc0000147e0, 0x199, 0x1998800, 0xc0000147e0) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:384 +0x40c encoding/json.(*decodeState).array(0xc000216bb0, 0x18df040, 0xc0001be540, 0x16, 0xc000216bd8, 0x10e405b) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:558 +0x365 encoding/json.(*decodeState).value(0xc000216bb0, 0x18df040, 0xc0001be540, 0x16, 0x16, 0x6e) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:360 +0x22f encoding/json.(*decodeState).unmarshal(0xc000216bb0, 0x18df040, 0xc0001be540, 0xc000216bd8, 0x0) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:180 +0x2c9 encoding/json.Unmarshal(0xc00029f200, 0x6, 0x200, 0x18df040, 0xc0001be540, 0x0, 0x0) /usr/local/Cellar/go/1.16/libexec/src/encoding/json/decode.go:107 +0x15d ``` (cherry picked from commit fe4e97afe0dc5f3afd5b550777d051b7c6c6f9a0) # Conflicts: # CHANGELOG_PENDING.md * fix conflict Co-authored-by: Anton Kaliaev --- CHANGELOG_PENDING.md | 1 + rpc/jsonrpc/types/types.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index c8a7ee663..b72257865 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -24,3 +24,4 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ### BUG FIXES +- [rpc/jsonrpc/server] \#6191 Correctly unmarshal `RPCRequest` when data is `null` (@melekes) diff --git a/rpc/jsonrpc/types/types.go b/rpc/jsonrpc/types/types.go index 54d17155c..4f05e14c2 100644 --- a/rpc/jsonrpc/types/types.go +++ b/rpc/jsonrpc/types/types.go @@ -57,27 +57,31 @@ type RPCRequest struct { // UnmarshalJSON custom JSON unmarshalling due to jsonrpcid being string or int func (req *RPCRequest) UnmarshalJSON(data []byte) error { - unsafeReq := &struct { + unsafeReq := struct { JSONRPC string `json:"jsonrpc"` ID interface{} `json:"id,omitempty"` Method string `json:"method"` Params json.RawMessage `json:"params"` // must be map[string]interface{} or []interface{} }{} + err := json.Unmarshal(data, &unsafeReq) if err != nil { return err } + + if unsafeReq.ID == nil { // notification + return nil + } + req.JSONRPC = unsafeReq.JSONRPC req.Method = unsafeReq.Method req.Params = unsafeReq.Params - if unsafeReq.ID == nil { - return nil - } id, err := idFromInterface(unsafeReq.ID) if err != nil { return err } req.ID = id + return nil }