Skip to content

Commit a5f2ba0

Browse files
committed
[FAB-2643] MsgCryptoSvc: NPE when no policyMgr found
Scenario: Peer gets an AliveMessage in gossip from an external organization, and the messageCryptoService tries to validate it. The validation first goes to the local MSP (and fails) so it tries validating using one of the channel policies (which were recently introduced), but it fails because the channelPolicyManagerGetter returns a nil policyManager from some reason. This results in a null dereference panic and the unexpected and sorrowful death of the peer. panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x756ff5] goroutine 45 [running]: panic(0xc1ad00, 0xc420016050) /opt/go/src/runtime/panic.go:500 +0x1a1 fabric/peer/gossip/mcs.(*mspMessageCryptoService).VerifyByChannel /opt/gopath/src/github.com/hyperledger/fabric/peer/gossip/mcs/mcs.go:234 github.com/hyperledger/fabric/peer/gossip/mcs.(*mspMessageCryptoService).Verify ... Full stacktrace available in the JIRA item. I added a nil check in 2 places and also added tests that check these corner cases. Change-Id: I3f45aff6cbf483258fcb4166f059e03647b947c8 Signed-off-by: Yacov Manevich <[email protected]>
1 parent ed7ed80 commit a5f2ba0

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

peer/gossip/mcs/mcs.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ limitations under the License.
1717
package mcs
1818

1919
import (
20+
"bytes"
2021
"errors"
2122
"fmt"
2223

23-
"bytes"
24-
2524
"github.com/hyperledger/fabric/bccsp"
2625
"github.com/hyperledger/fabric/bccsp/factory"
2726
"github.com/hyperledger/fabric/common/crypto"
@@ -156,6 +155,9 @@ func (s *mspMessageCryptoService) VerifyBlock(chainID common.ChainID, signedBloc
156155

157156
// Get the policy manager for channelID
158157
cpm, ok := s.channelPolicyManagerGetter.Manager(channelID)
158+
if cpm == nil {
159+
return fmt.Errorf("Could not acquire policy manager for channel %s", channelID)
160+
}
159161
// ok is true if it was the manager requested, or false if it is the default manager
160162
logger.Debugf("Got policy manager for channel [%s] with flag [%s]", channelID, ok)
161163

@@ -228,6 +230,9 @@ func (s *mspMessageCryptoService) VerifyByChannel(chainID common.ChainID, peerId
228230

229231
// Get the policy manager for channel chainID
230232
cpm, flag := s.channelPolicyManagerGetter.Manager(string(chainID))
233+
if cpm == nil {
234+
return fmt.Errorf("Could not acquire policy manager for channel %s", string(chainID))
235+
}
231236
logger.Debugf("Got policy manager for channel [%s] with flag [%s]", string(chainID), flag)
232237

233238
// Get channel reader policy

peer/gossip/mcs/mcs_test.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@ limitations under the License.
1717
package mcs
1818

1919
import (
20+
"fmt"
2021
"testing"
2122

23+
"github.com/golang/protobuf/proto"
2224
"github.com/hyperledger/fabric/bccsp"
2325
"github.com/hyperledger/fabric/bccsp/factory"
24-
25-
mockscrypto "github.com/hyperledger/fabric/common/mocks/crypto"
26-
27-
"github.com/golang/protobuf/proto"
2826
"github.com/hyperledger/fabric/common/crypto"
2927
"github.com/hyperledger/fabric/common/localmsp"
28+
mockscrypto "github.com/hyperledger/fabric/common/mocks/crypto"
3029
"github.com/hyperledger/fabric/common/policies"
3130
"github.com/hyperledger/fabric/common/util"
3231
"github.com/hyperledger/fabric/gossip/api"
@@ -79,6 +78,7 @@ func TestVerify(t *testing.T) {
7978
map[string]policies.Manager{
8079
"A": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Bob"), []byte("msg2")}}},
8180
"B": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Charlie"), []byte("msg3")}}},
81+
"C": nil,
8282
},
8383
},
8484
&mockscrypto.LocalSigner{Identity: []byte("Alice")},
@@ -87,6 +87,7 @@ func TestVerify(t *testing.T) {
8787
channelDeserializers: map[string]msp.IdentityDeserializer{
8888
"A": &mockIdentityDeserializer{[]byte("Bob"), []byte("msg2")},
8989
"B": &mockIdentityDeserializer{[]byte("Charlie"), []byte("msg3")},
90+
"C": &mockIdentityDeserializer{[]byte("Yacov"), []byte("msg4")},
9091
},
9192
},
9293
)
@@ -103,6 +104,12 @@ func TestVerify(t *testing.T) {
103104

104105
err = msgCryptoService.Verify(api.PeerIdentityType("Charlie"), sigma, msg)
105106
assert.Error(t, err, "Charlie should not verify the signature")
107+
108+
sigma, err = msgCryptoService.Sign(msg)
109+
assert.NoError(t, err)
110+
err = msgCryptoService.Verify(api.PeerIdentityType("Yacov"), sigma, msg)
111+
assert.Error(t, err)
112+
assert.Contains(t, fmt.Sprintf("%v", err), "Could not acquire policy manager")
106113
}
107114

108115
func TestVerifyBlock(t *testing.T) {
@@ -112,6 +119,7 @@ func TestVerifyBlock(t *testing.T) {
112119
"A": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Bob"), []byte("msg2")}}},
113120
"B": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Charlie"), []byte("msg3")}}},
114121
"C": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Alice"), []byte("msg1")}}},
122+
"D": &mockChannelPolicyManager{&mockPolicy{&mockIdentityDeserializer{[]byte("Alice"), []byte("msg1")}}},
115123
},
116124
}
117125

@@ -130,9 +138,15 @@ func TestVerifyBlock(t *testing.T) {
130138
// - Prepare testing valid block, Alice signs it.
131139
blockRaw, msg := mockBlock(t, "C", aliceSigner, nil)
132140
policyManagerGetter.managers["C"].(*mockChannelPolicyManager).mockPolicy.(*mockPolicy).deserializer.(*mockIdentityDeserializer).msg = msg
141+
blockRaw2, msg2 := mockBlock(t, "D", aliceSigner, nil)
142+
policyManagerGetter.managers["D"].(*mockChannelPolicyManager).mockPolicy.(*mockPolicy).deserializer.(*mockIdentityDeserializer).msg = msg2
133143

134144
// - Verify block
135145
assert.NoError(t, msgCryptoService.VerifyBlock([]byte("C"), blockRaw))
146+
delete(policyManagerGetter.managers, "D")
147+
nilPolMgrErr := msgCryptoService.VerifyBlock([]byte("D"), blockRaw2)
148+
assert.Contains(t, fmt.Sprintf("%v", nilPolMgrErr), "Could not acquire policy manager")
149+
assert.Error(t, nilPolMgrErr)
136150
assert.Error(t, msgCryptoService.VerifyBlock([]byte("A"), blockRaw))
137151
assert.Error(t, msgCryptoService.VerifyBlock([]byte("B"), blockRaw))
138152

0 commit comments

Comments
 (0)