Skip to content

Commit 44170d3

Browse files
author
Jason Yellick
committed
[FAB-6294] Fix stale reference to policy manager
The policy manager used to be stateful, and it was safe to retain a reference to it. However, this added considerable complexity and introduced the possibility for subtle races so it was turned into an immutable structure. The orderer signature filter was not updated to pull a fresh reference on each invocation, but instead still retains only a reference to the original policy manager. This CR updates the signature filter to fetch a fresh reference upon each invocation. Change-Id: Ibaf8a18cc992feaf737047c87ce8973450aa1d19 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent b33fb97 commit 44170d3

File tree

5 files changed

+28
-13
lines changed

5 files changed

+28
-13
lines changed

orderer/common/deliver/deliver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func (ds *deliverServer) deliverBlocks(srv ab.AtomicBroadcast_DeliverServer, env
138138

139139
lastConfigSequence := chain.Sequence()
140140

141-
sf := msgprocessor.NewSigFilter(policies.ChannelReaders, chain.PolicyManager())
141+
sf := msgprocessor.NewSigFilter(policies.ChannelReaders, chain)
142142
if err := sf.Apply(envelope); err != nil {
143143
logger.Warningf("[channel: %s] Received unauthorized deliver request from %s: %s", chdr.ChannelId, addr, err)
144144
return sendStatusReply(srv, cb.Status_FORBIDDEN)

orderer/common/msgprocessor/sigfilter.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,23 @@ import (
1515
"github.com/pkg/errors"
1616
)
1717

18+
// SigFilterSupport provides the resources required for the signature filter
19+
type SigFilterSupport interface {
20+
// PolicyManager returns a reference to the current policy manager
21+
PolicyManager() policies.Manager
22+
}
23+
1824
type sigFilter struct {
19-
policyName string
20-
policyManager policies.Manager
25+
policyName string
26+
support SigFilterSupport
2127
}
2228

2329
// NewSigFilter creates a new signature filter, at every evaluation, the policy manager is called
2430
// to retrieve the latest version of the policy
25-
func NewSigFilter(policyName string, policyManager policies.Manager) Rule {
31+
func NewSigFilter(policyName string, support SigFilterSupport) Rule {
2632
return &sigFilter{
27-
policyName: policyName,
28-
policyManager: policyManager,
33+
policyName: policyName,
34+
support: support,
2935
}
3036
}
3137

@@ -37,7 +43,7 @@ func (sf *sigFilter) Apply(message *cb.Envelope) error {
3743
return fmt.Errorf("could not convert message to signedData: %s", err)
3844
}
3945

40-
policy, ok := sf.policyManager.GetPolicy(sf.policyName)
46+
policy, ok := sf.support.PolicyManager().GetPolicy(sf.policyName)
4147
if !ok {
4248
return fmt.Errorf("could not find policy %s", sf.policyName)
4349
}

orderer/common/msgprocessor/sigfilter_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212

1313
"github.com/hyperledger/fabric/common/flogging"
14+
mockchannelconfig "github.com/hyperledger/fabric/common/mocks/config"
1415
mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
1516
cb "github.com/hyperledger/fabric/protos/common"
1617
"github.com/hyperledger/fabric/protos/utils"
@@ -34,26 +35,34 @@ func makeEnvelope() *cb.Envelope {
3435
}
3536

3637
func TestAccept(t *testing.T) {
37-
mpm := &mockpolicies.Manager{Policy: &mockpolicies.Policy{}}
38+
mpm := &mockchannelconfig.Resources{
39+
PolicyManagerVal: &mockpolicies.Manager{Policy: &mockpolicies.Policy{}},
40+
}
3841
assert.Nil(t, NewSigFilter("foo", mpm).Apply(makeEnvelope()), "Valid envelope and good policy")
3942
}
4043

4144
func TestMissingPolicy(t *testing.T) {
42-
mpm := &mockpolicies.Manager{}
45+
mpm := &mockchannelconfig.Resources{
46+
PolicyManagerVal: &mockpolicies.Manager{},
47+
}
4348
err := NewSigFilter("foo", mpm).Apply(makeEnvelope())
4449
assert.NotNil(t, err)
4550
assert.Regexp(t, "could not find policy", err.Error())
4651
}
4752

4853
func TestEmptyPayload(t *testing.T) {
49-
mpm := &mockpolicies.Manager{Policy: &mockpolicies.Policy{}}
54+
mpm := &mockchannelconfig.Resources{
55+
PolicyManagerVal: &mockpolicies.Manager{Policy: &mockpolicies.Policy{}},
56+
}
5057
err := NewSigFilter("foo", mpm).Apply(&cb.Envelope{})
5158
assert.NotNil(t, err)
5259
assert.Regexp(t, "could not convert message to signedData", err.Error())
5360
}
5461

5562
func TestErrorOnPolicy(t *testing.T) {
56-
mpm := &mockpolicies.Manager{Policy: &mockpolicies.Policy{Err: fmt.Errorf("Error")}}
63+
mpm := &mockchannelconfig.Resources{
64+
PolicyManagerVal: &mockpolicies.Manager{Policy: &mockpolicies.Policy{Err: fmt.Errorf("Error")}},
65+
}
5766
err := NewSigFilter("foo", mpm).Apply(makeEnvelope())
5867
assert.NotNil(t, err)
5968
assert.Equal(t, ErrPermissionDenied, errors.Cause(err))

orderer/common/msgprocessor/standardchannel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func CreateStandardChannelFilters(filterSupport channelconfig.Resources) *RuleSe
5353
return NewRuleSet([]Rule{
5454
EmptyRejectRule,
5555
NewSizeFilter(ordererConfig),
56-
NewSigFilter(policies.ChannelWriters, filterSupport.PolicyManager()),
56+
NewSigFilter(policies.ChannelWriters, filterSupport),
5757
})
5858
}
5959

orderer/common/msgprocessor/systemchannel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func CreateSystemChannelFilters(chainCreator ChainCreator, ledgerResources chann
5050
return NewRuleSet([]Rule{
5151
EmptyRejectRule,
5252
NewSizeFilter(ordererConfig),
53-
NewSigFilter(policies.ChannelWriters, ledgerResources.PolicyManager()),
53+
NewSigFilter(policies.ChannelWriters, ledgerResources),
5454
NewSystemChannelFilter(ledgerResources, chainCreator),
5555
})
5656
}

0 commit comments

Comments
 (0)