Skip to content

Commit 1b1e24c

Browse files
committed
[FAB-3892] check correctness of policy on cc2cc
The purpose of this change set is that for each cc2cc invocation, we check that the instantiated chaincode matches the installed one (if any) in terms of its instantiation policy, just to avoid repercussions from any rogue instantiation of a chaincode. Change-Id: I67368d1ef918edd6f6b92bf2cf4b99ea8eeb4e4b Signed-off-by: Alessandro Sorniotti <[email protected]>
1 parent 1cdbfc0 commit 1b1e24c

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

core/chaincode/handler.go

+6
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,12 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) {
12621262
errHandler([]byte(err.Error()), "[%s]Failed to get chaincoed data (%s) for invoked chaincode. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
12631263
return
12641264
}
1265+
1266+
err = ccprovider.CheckInsantiationPolicy(calledCcIns.ChaincodeName, cd.Version, cd)
1267+
if err != nil {
1268+
errHandler([]byte(err.Error()), "[%s]CheckInsantiationPolicy, error %s. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
1269+
return
1270+
}
12651271
} else {
12661272
//this is a system cc, just call it directly
12671273
cd = &ccprovider.ChaincodeData{Name: calledCcIns.ChaincodeName, Version: util.GetSysCCVersion()}

core/common/ccprovider/ccprovider.go

+33
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626

2727
"github.com/golang/protobuf/proto"
2828

29+
"bytes"
30+
2931
"github.com/hyperledger/fabric/common/flogging"
3032
"github.com/hyperledger/fabric/core/ledger"
3133
pb "github.com/hyperledger/fabric/protos/peer"
@@ -217,6 +219,37 @@ func PutChaincodeIntoFS(depSpec *pb.ChaincodeDeploymentSpec) error {
217219
}
218220
}
219221

222+
func CheckInsantiationPolicy(name, version string, cdLedger *ChaincodeData) error {
223+
// we retrieve info about this chaincode from the file system
224+
ccpack, err := GetChaincodeFromFS(name, version)
225+
if err != nil {
226+
return fmt.Errorf("Chaincode data for cc %s/%s was not found, error %s", name, version, err)
227+
}
228+
229+
// ccpack is guaranteed to be non-nil
230+
cdLocalFS := ccpack.GetChaincodeData()
231+
232+
// we have the info from the fs, check that the policy
233+
// matches the one on the file system if one was specified;
234+
// this check is required because the admin of this peer
235+
// might have specified instantiation policies for their
236+
// chaincode, for example to make sure that the chaincode
237+
// is only instantiated on certain channels; a malicious
238+
// peer on the other hand might have created a deploy
239+
// transaction that attempts to bypass the instantiation
240+
// policy. This check is there to ensure that this will not
241+
// happen, i.e. that the peer will refuse to invoke the
242+
// chaincode under these conditions. More info on
243+
// https://jira.hyperledger.org/browse/FAB-3156
244+
if cdLocalFS.InstantiationPolicy != nil {
245+
if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) {
246+
return fmt.Errorf("Instantiation policy mismatch for cc %s/%s", name, version)
247+
}
248+
}
249+
250+
return nil
251+
}
252+
220253
// GetCCPackage tries each known package implementation one by one
221254
// till the right package is found
222255
func GetCCPackage(buf []byte) (CCPackage, error) {

core/endorser/endorser.go

+2-25
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import (
1515

1616
"errors"
1717

18-
"bytes"
19-
2018
"github.com/hyperledger/fabric/common/policies"
2119
"github.com/hyperledger/fabric/common/util"
2220
"github.com/hyperledger/fabric/core/chaincode"
@@ -234,30 +232,9 @@ func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid st
234232
}
235233
version = cdLedger.Version
236234

237-
// we retrieve info about this chaincode from the file system
238-
ccpack, err := ccprovider.GetChaincodeFromFS(cid.Name, version)
235+
err = ccprovider.CheckInsantiationPolicy(cid.Name, version, cdLedger)
239236
if err != nil {
240-
return nil, nil, nil, nil, fmt.Errorf("chaincode %s/%s not found on the file system, error %s", cid.Name, version, err)
241-
}
242-
// ccpack is guaranteed to be non-nil
243-
cdLocalFS := ccpack.GetChaincodeData()
244-
245-
// we have the info from the fs, check that the policy
246-
// matches the one on the file system if one was specified;
247-
// this check is required because the admin of this peer
248-
// might have specified instantiation policies for their
249-
// chaincode, for example to make sure that the chaincode
250-
// is only instantiated on certain channels; a malicious
251-
// peer on the other hand might have created a deploy
252-
// transaction that attempts to bypass the instantiation
253-
// policy. This check is there to ensure that this will not
254-
// happen, i.e. that the peer will refuse to invoke the
255-
// chaincode under these conditions. More info on
256-
// https://jira.hyperledger.org/browse/FAB-3156
257-
if cdLocalFS.InstantiationPolicy != nil {
258-
if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) {
259-
return nil, nil, nil, nil, fmt.Errorf("instantiation policy mismatch for cc %s/%s", cid.Name, version)
260-
}
237+
return nil, nil, nil, nil, err
261238
}
262239
} else {
263240
version = util.GetSysCCVersion()

0 commit comments

Comments
 (0)