Skip to content

Commit 1acb65f

Browse files
committed
[FAB-3497] Removing the hash from gossip dataMsg
The hash field isn't used anywhere but in the protos comparator function to compare 2 ledger blocks disseminated. This imposes a security vulnerability: A malicious peer can send blocks with an arbitrary hash in the hash field of the DataMsg, and then these messages would enter the in-memory stores and fill up the memory. Since we have no use of the block hash of our own message, I am removing it entirely. Change-Id: Ic22ed3d06f102795c8f2a74b27063848affc926a Signed-off-by: Yacov Manevich <[email protected]>
1 parent 1195f2f commit 1acb65f

11 files changed

+137
-152
lines changed

gossip/comm/mock/mock_comm_test.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ func TestMockComm_PingPong(t *testing.T) {
7676
peerA.Send((&proto.GossipMessage{
7777
Content: &proto.GossipMessage_DataMsg{
7878
&proto.DataMessage{
79-
&proto.Payload{1, "", []byte("Ping")},
79+
&proto.Payload{
80+
SeqNum: 1,
81+
Data: []byte("Ping"),
82+
},
8083
}},
8184
}).NoopSign(), &comm.RemotePeer{"peerB", common.PKIidType("peerB")})
8285

@@ -88,7 +91,10 @@ func TestMockComm_PingPong(t *testing.T) {
8891
msg.Respond(&proto.GossipMessage{
8992
Content: &proto.GossipMessage_DataMsg{
9093
&proto.DataMessage{
91-
&proto.Payload{1, "", []byte("Pong")},
94+
&proto.Payload{
95+
SeqNum: 1,
96+
Data: []byte("Pong"),
97+
},
9298
}},
9399
})
94100

gossip/gossip/channel/channel_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -1393,7 +1393,6 @@ func dataMsgOfChannel(seqnum uint64, channel common.ChainID) *proto.SignedGossip
13931393
DataMsg: &proto.DataMessage{
13941394
Payload: &proto.Payload{
13951395
Data: []byte{},
1396-
Hash: "",
13971396
SeqNum: seqnum,
13981397
},
13991398
},
@@ -1441,7 +1440,6 @@ func createDataMsg(seqnum uint64, channel common.ChainID) *proto.SignedGossipMes
14411440
DataMsg: &proto.DataMessage{
14421441
Payload: &proto.Payload{
14431442
Data: []byte{},
1444-
Hash: "",
14451443
SeqNum: seqnum,
14461444
},
14471445
},

gossip/gossip/gossip_test.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ func TestPull(t *testing.T) {
330330
}
331331

332332
for i := 1; i <= msgsCount2Send; i++ {
333-
boot.Gossip(createDataMsg(uint64(i), []byte{}, "", common.ChainID("A")))
333+
boot.Gossip(createDataMsg(uint64(i), []byte{}, common.ChainID("A")))
334334
}
335335

336336
waitUntilOrFail(t, knowAll)
@@ -564,7 +564,7 @@ func TestDissemination(t *testing.T) {
564564
t.Log("Membership establishment took", time.Since(membershipTime))
565565

566566
for i := 1; i <= msgsCount2Send; i++ {
567-
boot.Gossip(createDataMsg(uint64(i), []byte{}, "", common.ChainID("A")))
567+
boot.Gossip(createDataMsg(uint64(i), []byte{}, common.ChainID("A")))
568568
}
569569

570570
t2 := time.Now()
@@ -902,8 +902,8 @@ func TestDataLeakage(t *testing.T) {
902902
}
903903

904904
t1 = time.Now()
905-
peers[0].Gossip(createDataMsg(1, []byte{}, "", channels[0]))
906-
peers[n/2].Gossip(createDataMsg(2, []byte{}, "", channels[1]))
905+
peers[0].Gossip(createDataMsg(1, []byte{}, channels[0]))
906+
peers[n/2].Gossip(createDataMsg(2, []byte{}, channels[1]))
907907
waitUntilOrFailBlocking(t, gotMessages)
908908
t.Log("Dissemination took", time.Since(t1))
909909
stop := func() {
@@ -972,7 +972,7 @@ func TestDisseminateAll2All(t *testing.T) {
972972
blockStartIndex := i * 10
973973
for j := 0; j < 10; j++ {
974974
blockSeq := uint64(j + blockStartIndex)
975-
peers[i].Gossip(createDataMsg(blockSeq, []byte{}, "", common.ChainID("A")))
975+
peers[i].Gossip(createDataMsg(blockSeq, []byte{}, common.ChainID("A")))
976976
}
977977
}(i)
978978
}
@@ -1044,7 +1044,7 @@ func TestEndedGoroutines(t *testing.T) {
10441044
ensureGoroutineExit(t)
10451045
}
10461046

1047-
func createDataMsg(seqnum uint64, data []byte, hash string, channel common.ChainID) *proto.GossipMessage {
1047+
func createDataMsg(seqnum uint64, data []byte, channel common.ChainID) *proto.GossipMessage {
10481048
return &proto.GossipMessage{
10491049
Channel: []byte(channel),
10501050
Nonce: 0,
@@ -1053,7 +1053,6 @@ func createDataMsg(seqnum uint64, data []byte, hash string, channel common.Chain
10531053
DataMsg: &proto.DataMessage{
10541054
Payload: &proto.Payload{
10551055
Data: data,
1056-
Hash: hash,
10571056
SeqNum: seqnum,
10581057
},
10591058
},

gossip/gossip/pull/pullstore_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,6 @@ func dataMsg(seqNum int) *proto.SignedGossipMessage {
332332
DataMsg: &proto.DataMessage{
333333
Payload: &proto.Payload{
334334
Data: []byte{},
335-
Hash: "",
336335
SeqNum: uint64(seqNum),
337336
},
338337
},

gossip/state/payloads_buffer_test.go

+4-19
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package state
1818

1919
import (
2020
"crypto/rand"
21-
"fmt"
2221
"sync"
2322
"sync/atomic"
2423
"testing"
@@ -33,30 +32,16 @@ func init() {
3332
util.SetupTestLogging()
3433
}
3534

36-
func uuid() (string, error) {
37-
uuid := make([]byte, 16)
38-
_, err := rand.Read(uuid)
39-
if err != nil {
40-
return "", err
41-
}
42-
uuid[8] = uuid[8]&^0xc0 | 0x80
43-
44-
uuid[6] = uuid[6]&^0xf0 | 0x40
45-
return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
46-
}
47-
4835
func randomPayloadWithSeqNum(seqNum uint64) (*proto.Payload, error) {
4936
data := make([]byte, 64)
5037
_, err := rand.Read(data)
5138
if err != nil {
5239
return nil, err
5340
}
54-
uuid, err := uuid()
55-
if err != nil {
56-
return nil, err
57-
}
58-
59-
return &proto.Payload{seqNum, uuid, data}, nil
41+
return &proto.Payload{
42+
SeqNum: seqNum,
43+
Data: data,
44+
}, nil
6045
}
6146

6247
func TestNewPayloadsBuffer(t *testing.T) {

gossip/state/state.go

-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ func (s *GossipStateProviderImpl) handleStateRequest(msg proto.ReceivedMessage)
343343
response.Payloads = append(response.Payloads, &proto.Payload{
344344
SeqNum: seqNum,
345345
Data: blockBytes,
346-
Hash: string(blocks[0].Header.Hash()),
347346
})
348347
}
349348
// Sending back response with missing blocks

gossip/state/state_test.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,10 @@ func TestAccessControl(t *testing.T) {
394394
for i := 1; i <= msgCount; i++ {
395395
rawblock := pcomm.NewBlock(uint64(i), []byte{})
396396
if b, err := pb.Marshal(rawblock); err == nil {
397-
payload := &proto.Payload{uint64(i), "", b}
397+
payload := &proto.Payload{
398+
SeqNum: uint64(i),
399+
Data: b,
400+
}
398401
bootstrapSet[0].s.AddPayload(payload)
399402
} else {
400403
t.Fail()
@@ -550,7 +553,10 @@ func TestNewGossipStateProvider_SendingManyMessages(t *testing.T) {
550553
for i := 1; i <= msgCount; i++ {
551554
rawblock := pcomm.NewBlock(uint64(i), []byte{})
552555
if b, err := pb.Marshal(rawblock); err == nil {
553-
payload := &proto.Payload{uint64(i), "", b}
556+
payload := &proto.Payload{
557+
SeqNum: uint64(i),
558+
Data: b,
559+
}
554560
bootstrapSet[0].s.AddPayload(payload)
555561
} else {
556562
t.Fail()
@@ -682,7 +688,10 @@ func TestNewGossipStateProvider_BatchingOfStateRequest(t *testing.T) {
682688
for i := 1; i <= msgCount; i++ {
683689
rawblock := pcomm.NewBlock(uint64(i), []byte{})
684690
if b, err := pb.Marshal(rawblock); err == nil {
685-
payload := &proto.Payload{uint64(i), "", b}
691+
payload := &proto.Payload{
692+
SeqNum: uint64(i),
693+
Data: b,
694+
}
686695
bootPeer.s.AddPayload(payload)
687696
} else {
688697
t.Fail()

protos/gossip/extensions.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,7 @@ func (mc *msgComparator) identityInvalidationPolicy(thisIdentityMsg *PeerIdentit
8585

8686
func (mc *msgComparator) dataInvalidationPolicy(thisDataMsg *DataMessage, thatDataMsg *DataMessage) common.InvalidationResult {
8787
if thisDataMsg.Payload.SeqNum == thatDataMsg.Payload.SeqNum {
88-
if thisDataMsg.Payload.Hash == thatDataMsg.Payload.Hash {
89-
return common.MessageInvalidated
90-
}
91-
return common.MessageNoAction
88+
return common.MessageInvalidated
9289
}
9390

9491
diff := abs(thisDataMsg.Payload.SeqNum, thatDataMsg.Payload.SeqNum)

protos/gossip/extensions_test.go

+19-23
Original file line numberDiff line numberDiff line change
@@ -273,17 +273,15 @@ func TestDataMessageInvalidation(t *testing.T) {
273273
comparator := NewGossipMessageComparator(5)
274274

275275
data := []byte{1, 1, 1}
276-
sMsg1 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(1, "hash", data))
277-
sMsg2 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(1, "hash", data))
278-
sMsg3 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(1, "newHash", data))
279-
sMsg4 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(2, "newHash", data))
280-
sMsg5 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(7, "newHash", data))
276+
sMsg1 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(1, data))
277+
sMsg1Clone := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(1, data))
278+
sMsg3 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(2, data))
279+
sMsg4 := signedGossipMessage("testChannel", GossipMessage_EMPTY, dataMessage(7, data))
281280

282-
assert.Equal(t, comparator(sMsg1, sMsg2), common.MessageInvalidated)
281+
assert.Equal(t, comparator(sMsg1, sMsg1Clone), common.MessageInvalidated)
283282
assert.Equal(t, comparator(sMsg1, sMsg3), common.MessageNoAction)
284-
assert.Equal(t, comparator(sMsg1, sMsg4), common.MessageNoAction)
285-
assert.Equal(t, comparator(sMsg1, sMsg5), common.MessageInvalidated)
286-
assert.Equal(t, comparator(sMsg5, sMsg1), common.MessageInvalidates)
283+
assert.Equal(t, comparator(sMsg1, sMsg4), common.MessageInvalidated)
284+
assert.Equal(t, comparator(sMsg4, sMsg1), common.MessageInvalidates)
287285
}
288286

289287
func TestIdentityMessagesInvalidation(t *testing.T) {
@@ -376,7 +374,7 @@ func TestCheckGossipMessageTypes(t *testing.T) {
376374
assert.True(t, msg.IsAliveMsg())
377375

378376
// Create gossip data message
379-
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, "hash", []byte{1, 2, 3, 4, 5}))
377+
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, []byte{1, 2, 3, 4, 5}))
380378
assert.True(t, msg.IsDataMsg())
381379

382380
// Create data request message
@@ -436,7 +434,6 @@ func TestCheckGossipMessageTypes(t *testing.T) {
436434
StateResponse: &RemoteStateResponse{
437435
Payloads: []*Payload{&Payload{
438436
SeqNum: 1,
439-
Hash: "hash",
440437
Data: []byte{1, 2, 3, 4, 5},
441438
}},
442439
},
@@ -497,7 +494,7 @@ func TestGossipPullMessageType(t *testing.T) {
497494
assert.Equal(t, msg.GetPullMsgType(), PullMsgType_IDENTITY_MSG)
498495

499496
// Create gossip data message
500-
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, "hash", []byte{1, 2, 3, 4, 5}))
497+
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, []byte{1, 2, 3, 4, 5}))
501498
assert.True(t, msg.IsDataMsg())
502499
assert.Equal(t, msg.GetPullMsgType(), PullMsgType_UNDEFINED)
503500
}
@@ -506,30 +503,30 @@ func TestGossipMessageDataMessageTagType(t *testing.T) {
506503
var msg *SignedGossipMessage
507504
channelID := "testID1"
508505

509-
msg = signedGossipMessage(channelID, GossipMessage_CHAN_AND_ORG, dataMessage(1, "hash", []byte{1}))
506+
msg = signedGossipMessage(channelID, GossipMessage_CHAN_AND_ORG, dataMessage(1, []byte{1}))
510507
assert.True(t, msg.IsChannelRestricted())
511508
assert.True(t, msg.IsOrgRestricted())
512509
assert.NoError(t, msg.IsTagLegal())
513510

514-
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, "hash", []byte{1}))
511+
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, []byte{1}))
515512
assert.Error(t, msg.IsTagLegal())
516513

517-
msg = signedGossipMessage(channelID, GossipMessage_UNDEFINED, dataMessage(1, "hash", []byte{1}))
514+
msg = signedGossipMessage(channelID, GossipMessage_UNDEFINED, dataMessage(1, []byte{1}))
518515
assert.Error(t, msg.IsTagLegal())
519516

520-
msg = signedGossipMessage(channelID, GossipMessage_ORG_ONLY, dataMessage(1, "hash", []byte{1}))
517+
msg = signedGossipMessage(channelID, GossipMessage_ORG_ONLY, dataMessage(1, []byte{1}))
521518
assert.False(t, msg.IsChannelRestricted())
522519
assert.True(t, msg.IsOrgRestricted())
523520

524-
msg = signedGossipMessage(channelID, GossipMessage_CHAN_OR_ORG, dataMessage(1, "hash", []byte{1}))
521+
msg = signedGossipMessage(channelID, GossipMessage_CHAN_OR_ORG, dataMessage(1, []byte{1}))
525522
assert.True(t, msg.IsChannelRestricted())
526523
assert.False(t, msg.IsOrgRestricted())
527524

528-
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, "hash", []byte{1}))
525+
msg = signedGossipMessage(channelID, GossipMessage_EMPTY, dataMessage(1, []byte{1}))
529526
assert.False(t, msg.IsChannelRestricted())
530527
assert.False(t, msg.IsOrgRestricted())
531528

532-
msg = signedGossipMessage(channelID, GossipMessage_UNDEFINED, dataMessage(1, "hash", []byte{1}))
529+
msg = signedGossipMessage(channelID, GossipMessage_UNDEFINED, dataMessage(1, []byte{1}))
533530
assert.False(t, msg.IsChannelRestricted())
534531
assert.False(t, msg.IsOrgRestricted())
535532
}
@@ -774,7 +771,7 @@ func TestSignedGossipMessage_Verify(t *testing.T) {
774771

775772
func TestEnvelope(t *testing.T) {
776773
dataMsg := &GossipMessage{
777-
Content: dataMessage(1, "hash", []byte("data")),
774+
Content: dataMessage(1, []byte("data")),
778775
}
779776
bytes, err := proto.Marshal(dataMsg)
780777
assert.NoError(t, err)
@@ -791,7 +788,7 @@ func TestEnvelope(t *testing.T) {
791788

792789
func TestEnvelope_SignSecret(t *testing.T) {
793790
dataMsg := &GossipMessage{
794-
Content: dataMessage(1, "hash", []byte("data")),
791+
Content: dataMessage(1, []byte("data")),
795792
}
796793
bytes, err := proto.Marshal(dataMsg)
797794
assert.NoError(t, err)
@@ -851,12 +848,11 @@ func stateInfoMessage(incNumber uint64, seqNum uint64, pkid []byte, mac []byte)
851848
}
852849
}
853850

854-
func dataMessage(seqNum uint64, hash string, data []byte) *GossipMessage_DataMsg {
851+
func dataMessage(seqNum uint64, data []byte) *GossipMessage_DataMsg {
855852
return &GossipMessage_DataMsg{
856853
DataMsg: &DataMessage{
857854
Payload: &Payload{
858855
SeqNum: seqNum,
859-
Hash: hash,
860856
Data: data,
861857
},
862858
},

0 commit comments

Comments
 (0)