Skip to content

Commit

Permalink
[FAB-3892] check correctness of policy on cc2cc
Browse files Browse the repository at this point in the history
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 <ale.linux@sopit.net>
  • Loading branch information
ale-linux committed Jun 6, 2017
1 parent 1cdbfc0 commit 1b1e24c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 25 deletions.
6 changes: 6 additions & 0 deletions core/chaincode/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,12 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) {
errHandler([]byte(err.Error()), "[%s]Failed to get chaincoed data (%s) for invoked chaincode. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
return
}

err = ccprovider.CheckInsantiationPolicy(calledCcIns.ChaincodeName, cd.Version, cd)
if err != nil {
errHandler([]byte(err.Error()), "[%s]CheckInsantiationPolicy, error %s. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
return
}
} else {
//this is a system cc, just call it directly
cd = &ccprovider.ChaincodeData{Name: calledCcIns.ChaincodeName, Version: util.GetSysCCVersion()}
Expand Down
33 changes: 33 additions & 0 deletions core/common/ccprovider/ccprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (

"github.com/golang/protobuf/proto"

"bytes"

"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/core/ledger"
pb "github.com/hyperledger/fabric/protos/peer"
Expand Down Expand Up @@ -217,6 +219,37 @@ func PutChaincodeIntoFS(depSpec *pb.ChaincodeDeploymentSpec) error {
}
}

func CheckInsantiationPolicy(name, version string, cdLedger *ChaincodeData) error {
// we retrieve info about this chaincode from the file system
ccpack, err := GetChaincodeFromFS(name, version)
if err != nil {
return fmt.Errorf("Chaincode data for cc %s/%s was not found, error %s", name, version, err)
}

// ccpack is guaranteed to be non-nil
cdLocalFS := ccpack.GetChaincodeData()

// we have the info from the fs, check that the policy
// matches the one on the file system if one was specified;
// this check is required because the admin of this peer
// might have specified instantiation policies for their
// chaincode, for example to make sure that the chaincode
// is only instantiated on certain channels; a malicious
// peer on the other hand might have created a deploy
// transaction that attempts to bypass the instantiation
// policy. This check is there to ensure that this will not
// happen, i.e. that the peer will refuse to invoke the
// chaincode under these conditions. More info on
// https://jira.hyperledger.org/browse/FAB-3156
if cdLocalFS.InstantiationPolicy != nil {
if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) {
return fmt.Errorf("Instantiation policy mismatch for cc %s/%s", name, version)
}
}

return nil
}

// GetCCPackage tries each known package implementation one by one
// till the right package is found
func GetCCPackage(buf []byte) (CCPackage, error) {
Expand Down
27 changes: 2 additions & 25 deletions core/endorser/endorser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (

"errors"

"bytes"

"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/chaincode"
Expand Down Expand Up @@ -234,30 +232,9 @@ func (e *Endorser) simulateProposal(ctx context.Context, chainID string, txid st
}
version = cdLedger.Version

// we retrieve info about this chaincode from the file system
ccpack, err := ccprovider.GetChaincodeFromFS(cid.Name, version)
err = ccprovider.CheckInsantiationPolicy(cid.Name, version, cdLedger)
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("chaincode %s/%s not found on the file system, error %s", cid.Name, version, err)
}
// ccpack is guaranteed to be non-nil
cdLocalFS := ccpack.GetChaincodeData()

// we have the info from the fs, check that the policy
// matches the one on the file system if one was specified;
// this check is required because the admin of this peer
// might have specified instantiation policies for their
// chaincode, for example to make sure that the chaincode
// is only instantiated on certain channels; a malicious
// peer on the other hand might have created a deploy
// transaction that attempts to bypass the instantiation
// policy. This check is there to ensure that this will not
// happen, i.e. that the peer will refuse to invoke the
// chaincode under these conditions. More info on
// https://jira.hyperledger.org/browse/FAB-3156
if cdLocalFS.InstantiationPolicy != nil {
if !bytes.Equal(cdLocalFS.InstantiationPolicy, cdLedger.InstantiationPolicy) {
return nil, nil, nil, nil, fmt.Errorf("instantiation policy mismatch for cc %s/%s", cid.Name, version)
}
return nil, nil, nil, nil, err
}
} else {
version = util.GetSysCCVersion()
Expand Down

0 comments on commit 1b1e24c

Please sign in to comment.