Skip to content

Commit eb019ee

Browse files
committed
[FAB-3155] LSCC security checks at validation time
This change set checks that - upon cc deploy and upgrade - the tx complies with the instantiation policy specified in the cc packge (for deploy) and in the cc info in the ledger (for upgrade). The committer code is essentially performing again the checks that lscc performs at proposal time, to ensure that no one can circumvent instantiation policies. Furthermore, we validate the read-write set of a cc deploy/upgrade and make sure that it is consistent with the invocation arguments. Finally, we make sure that LSCC deploy/upgrade transactions do not contain writes to namespaces other than LSCC's and the chaincode that is being deployed/upgraded. Change-Id: Id11fc359a8c77fa58c8a966a7c324075944ae22b Signed-off-by: Alessandro Sorniotti <[email protected]>
1 parent 23866ec commit eb019ee

File tree

7 files changed

+1395
-27
lines changed

7 files changed

+1395
-27
lines changed

common/mocks/ledger/queryexecutor.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package ledger
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/hyperledger/fabric/common/ledger"
23+
)
24+
25+
type MockQueryExecutor struct {
26+
// State keeps all namepspaces
27+
State map[string]map[string][]byte
28+
}
29+
30+
func NewMockQueryExecutor(state map[string]map[string][]byte) *MockQueryExecutor {
31+
return &MockQueryExecutor{
32+
State: state,
33+
}
34+
}
35+
36+
func (m *MockQueryExecutor) GetState(namespace string, key string) ([]byte, error) {
37+
ns := m.State[namespace]
38+
if ns == nil {
39+
return nil, fmt.Errorf("Could not retrieve namespace %s", namespace)
40+
}
41+
42+
return ns[key], nil
43+
}
44+
45+
func (m *MockQueryExecutor) GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error) {
46+
return nil, nil
47+
48+
}
49+
50+
func (m *MockQueryExecutor) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ledger.ResultsIterator, error) {
51+
return nil, nil
52+
53+
}
54+
55+
func (m *MockQueryExecutor) ExecuteQuery(namespace, query string) (ledger.ResultsIterator, error) {
56+
return nil, nil
57+
}
58+
59+
func (m *MockQueryExecutor) Done() {
60+
61+
}

core/common/sysccprovider/sysccprovider.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ limitations under the License.
1616

1717
package sysccprovider
1818

19-
import "github.com/golang/protobuf/proto"
19+
import (
20+
"github.com/golang/protobuf/proto"
21+
"github.com/hyperledger/fabric/core/ledger"
22+
)
2023

2124
// SystemChaincodeProvider provides an abstraction layer that is
2225
// used for different packages to interact with code in the
@@ -29,6 +32,12 @@ type SystemChaincodeProvider interface {
2932
// IsSysCCAndNotInvokableCC2CC returns true if the supplied chaincode
3033
// is a system chaincode and is not invokable through a cc2cc invocation
3134
IsSysCCAndNotInvokableCC2CC(name string) bool
35+
36+
// GetQueryExecutorForLedger returns a query executor for the
37+
// ledger of the supplied channel.
38+
// That's useful for system chaincodes that require unfettered
39+
// access to the ledger
40+
GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error)
3241
}
3342

3443
var sccFactory SystemChaincodeProviderFactory

core/scc/lscc/lscc_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
putils "github.com/hyperledger/fabric/protos/utils"
4444

4545
cutil "github.com/hyperledger/fabric/core/container/util"
46+
"github.com/hyperledger/fabric/core/ledger"
4647
pb "github.com/hyperledger/fabric/protos/peer"
4748
"github.com/hyperledger/fabric/protos/utils"
4849
)
@@ -67,6 +68,10 @@ func (c *mocksccProviderImpl) IsSysCCAndNotInvokableCC2CC(name string) bool {
6768
return false
6869
}
6970

71+
func (c *mocksccProviderImpl) GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error) {
72+
return nil, nil
73+
}
74+
7075
func register(stub *shim.MockStub, ccname string) error {
7176
args := [][]byte{[]byte("register"), []byte(ccname)}
7277
if res := stub.MockInvoke("1", args); res.Status != shim.OK {

core/scc/sccproviderimpl.go

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

1919
import (
20+
"fmt"
21+
2022
"github.com/hyperledger/fabric/core/common/sysccprovider"
23+
"github.com/hyperledger/fabric/core/ledger"
24+
"github.com/hyperledger/fabric/core/peer"
2125
)
2226

2327
// sccProviderFactory implements the sysccprovider.SystemChaincodeProviderFactory
@@ -50,3 +54,12 @@ func (c *sccProviderImpl) IsSysCC(name string) bool {
5054
func (c *sccProviderImpl) IsSysCCAndNotInvokableCC2CC(name string) bool {
5155
return IsSysCCAndNotInvokableCC2CC(name)
5256
}
57+
58+
func (c *sccProviderImpl) GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error) {
59+
l := peer.GetLedger(cid)
60+
if l == nil {
61+
return nil, fmt.Errorf("Could not retrieve ledger for channel %s", cid)
62+
}
63+
64+
return l.NewQueryExecutor()
65+
}

0 commit comments

Comments
 (0)