Skip to content

Commit 8bdb9a4

Browse files
author
Srinivasan Muralidharan
committed
[FAB-4751] disallow external CC from registering
Externals chaincodes are allowed to register even when not in dev mode. There is no reason to. This CR does two things . dissalows external chaincode from registering when not in dev mode . tightens the window between launch and registration patch 2 . fixed docker UT . added some tests patch 3 . fixed a typo in a log . removed WIP Change-Id: I733b058ac8ec5f7922110e691cc48fa2c6d3d04c Signed-off-by: Srinivasan Muralidharan <[email protected]>
1 parent feded5a commit 8bdb9a4

File tree

6 files changed

+65
-20
lines changed

6 files changed

+65
-20
lines changed

core/chaincode/chaincode_support.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@ func GetChain() *ChaincodeSupport {
102102
return theChaincodeSupport
103103
}
104104

105-
//call this under lock
106105
func (chaincodeSupport *ChaincodeSupport) preLaunchSetup(chaincode string) chan bool {
106+
chaincodeSupport.runningChaincodes.Lock()
107+
defer chaincodeSupport.runningChaincodes.Unlock()
107108
//register placeholder Handler. This will be transferred in registerHandler
108109
//NOTE: from this point, existence of handler for this chaincode means the chaincode
109110
//is in the process of getting started (or has been started)
@@ -261,6 +262,11 @@ func (chaincodeSupport *ChaincodeSupport) registerHandler(chaincodehandler *Hand
261262
chaincodehandler.readyNotify = chrte2.handler.readyNotify
262263
chrte2.handler = chaincodehandler
263264
} else {
265+
if chaincodeSupport.userRunsCC == false {
266+
//this chaincode was not launched by the peer and is attempting
267+
//to register. Don't allow this.
268+
return fmt.Errorf("peer will not accepting external chaincode connection %v (except in dev mode)", chaincodehandler.ChaincodeID)
269+
}
264270
chaincodeSupport.runningChaincodes.chaincodeMap[key] = &chaincodeRTEnv{handler: chaincodehandler}
265271
}
266272

@@ -405,8 +411,6 @@ func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.
405411
return fmt.Errorf("Error chaincode is being launched: %s", canName)
406412
}
407413

408-
//chaincodeHasBeenLaunch false... its not in the map, add it and proceed to launch
409-
notfy := chaincodeSupport.preLaunchSetup(canName)
410414
chaincodeSupport.runningChaincodes.Unlock()
411415

412416
//launch the chaincode
@@ -422,7 +426,16 @@ func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.
422426

423427
vmtype, _ := chaincodeSupport.getVMType(cds)
424428

425-
sir := container.StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID, Version: cccid.Version}, Builder: builder, Args: args, Env: env}
429+
//set up the shadow handler JIT before container launch to
430+
//reduce window of when an external chaincode can sneak in
431+
//and use the launching context and make it its own
432+
var notfy chan bool
433+
preLaunchFunc := func() error {
434+
notfy = chaincodeSupport.preLaunchSetup(canName)
435+
return nil
436+
}
437+
438+
sir := container.StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID, Version: cccid.Version}, Builder: builder, Args: args, Env: env, PrelaunchFunc: preLaunchFunc}
426439

427440
ipcCtxt := context.WithValue(ctxt, ccintf.GetCCHandlerKey(), chaincodeSupport)
428441

core/container/api/core.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ import (
2525
)
2626

2727
type BuildSpecFactory func() (io.Reader, error)
28+
type PrelaunchFunc func() error
2829

2930
//abstract virtual image for supporting arbitrary virual machines
3031
type VM interface {
3132
Deploy(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, reader io.Reader) error
32-
Start(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, builder BuildSpecFactory) error
33+
Start(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, builder BuildSpecFactory, preLaunchFunc PrelaunchFunc) error
3334
Stop(ctxt context.Context, ccid ccintf.CCID, timeout uint, dontkill bool, dontremove bool) error
3435
Destroy(ctxt context.Context, ccid ccintf.CCID, force bool, noprune bool) error
3536
GetVMName(ccID ccintf.CCID) (string, error)

core/container/controller.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,16 @@ func (bp CreateImageReq) getCCID() ccintf.CCID {
153153
//StartImageReq - properties for starting a container.
154154
type StartImageReq struct {
155155
ccintf.CCID
156-
Builder api.BuildSpecFactory
157-
Args []string
158-
Env []string
156+
Builder api.BuildSpecFactory
157+
Args []string
158+
Env []string
159+
PrelaunchFunc api.PrelaunchFunc
159160
}
160161

161162
func (si StartImageReq) do(ctxt context.Context, v api.VM) VMCResp {
162163
var resp VMCResp
163164

164-
if err := v.Start(ctxt, si.CCID, si.Args, si.Env, si.Builder); err != nil {
165+
if err := v.Start(ctxt, si.CCID, si.Args, si.Env, si.Builder, si.PrelaunchFunc); err != nil {
165166
resp = VMCResp{Err: err}
166167
} else {
167168
resp = VMCResp{}

core/container/dockercontroller/dockercontroller.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func (vm *DockerVM) Deploy(ctxt context.Context, ccid ccintf.CCID,
207207

208208
//Start starts a container using a previously created docker image
209209
func (vm *DockerVM) Start(ctxt context.Context, ccid ccintf.CCID,
210-
args []string, env []string, builder container.BuildSpecFactory) error {
210+
args []string, env []string, builder container.BuildSpecFactory, prelaunchFunc container.PrelaunchFunc) error {
211211
imageID, err := vm.GetVMName(ccid)
212212
if err != nil {
213213
return err
@@ -330,6 +330,12 @@ func (vm *DockerVM) Start(ctxt context.Context, ccid ccintf.CCID,
330330
}()
331331
}
332332

333+
if prelaunchFunc != nil {
334+
if err = prelaunchFunc(); err != nil {
335+
return err
336+
}
337+
}
338+
333339
// start container with HostConfig was deprecated since v1.10 and removed in v1.2
334340
err = client.StartContainer(containerID, nil)
335341
if err != nil {

core/container/dockercontroller/dockercontroller_test.go

+27-9
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,19 @@ func Test_Start(t *testing.T) {
106106
// case 1: getMockClient returns error
107107
dvm.getClientFnc = getMockClient
108108
getClientErr = true
109-
err := dvm.Start(ctx, ccid, args, env, nil)
109+
err := dvm.Start(ctx, ccid, args, env, nil, nil)
110110
testerr(t, err, false)
111111
getClientErr = false
112112

113113
// case 2: dockerClient.CreateContainer returns error
114114
createErr = true
115-
err = dvm.Start(ctx, ccid, args, env, nil)
115+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
116116
testerr(t, err, false)
117117
createErr = false
118118

119119
// case 3: dockerClient.CreateContainer returns docker.noSuchImgErr
120120
noSuchImgErr = true
121-
err = dvm.Start(ctx, ccid, args, env, nil)
121+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
122122
testerr(t, err, false)
123123

124124
chaincodePath := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
@@ -136,35 +136,53 @@ func Test_Start(t *testing.T) {
136136
// docker.noSuchImgErr and dockerClient.Start returns error
137137
viper.Set("vm.docker.attachStdout", true)
138138
startErr = true
139-
err = dvm.Start(ctx, ccid, args, env, bldr)
139+
err = dvm.Start(ctx, ccid, args, env, bldr, nil)
140140
testerr(t, err, false)
141141
startErr = false
142142

143143
// Success cases
144-
err = dvm.Start(ctx, ccid, args, env, bldr)
144+
err = dvm.Start(ctx, ccid, args, env, bldr, nil)
145145
testerr(t, err, true)
146146
noSuchImgErr = false
147147

148148
// dockerClient.StopContainer returns error
149149
stopErr = true
150-
err = dvm.Start(ctx, ccid, args, env, nil)
150+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
151151
testerr(t, err, true)
152152
stopErr = false
153153

154154
// dockerClient.KillContainer returns error
155155
killErr = true
156-
err = dvm.Start(ctx, ccid, args, env, nil)
156+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
157157
testerr(t, err, true)
158158
killErr = false
159159

160160
// dockerClient.RemoveContainer returns error
161161
removeErr = true
162-
err = dvm.Start(ctx, ccid, args, env, nil)
162+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
163163
testerr(t, err, true)
164164
removeErr = false
165165

166-
err = dvm.Start(ctx, ccid, args, env, nil)
166+
err = dvm.Start(ctx, ccid, args, env, nil, nil)
167167
testerr(t, err, true)
168+
169+
//test preLaunchFunc works correctly
170+
preLaunchStr := "notset"
171+
preLaunchFunc := func() error {
172+
preLaunchStr = "set"
173+
return nil
174+
}
175+
176+
err = dvm.Start(ctx, ccid, args, env, nil, preLaunchFunc)
177+
testerr(t, err, true)
178+
assert.Equal(t, preLaunchStr, "set")
179+
180+
preLaunchFunc = func() error {
181+
return fmt.Errorf("testing error path")
182+
}
183+
184+
err = dvm.Start(ctx, ccid, args, env, nil, preLaunchFunc)
185+
testerr(t, err, false)
168186
}
169187

170188
func Test_Stop(t *testing.T) {

core/container/inproccontroller/inproccontroller.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func (ipc *inprocContainer) launchInProc(ctxt context.Context, id string, args [
154154
}
155155

156156
//Start starts a previously registered system codechain
157-
func (vm *InprocVM) Start(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, builder container.BuildSpecFactory) error {
157+
func (vm *InprocVM) Start(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, builder container.BuildSpecFactory, prelaunchFunc container.PrelaunchFunc) error {
158158
path := ccid.ChaincodeSpec.ChaincodeId.Path
159159

160160
ipctemplate := typeRegistry[path]
@@ -182,6 +182,12 @@ func (vm *InprocVM) Start(ctxt context.Context, ccid ccintf.CCID, args []string,
182182
return fmt.Errorf("in-process communication generator not supplied")
183183
}
184184

185+
if prelaunchFunc != nil {
186+
if err = prelaunchFunc(); err != nil {
187+
return err
188+
}
189+
}
190+
185191
ipc.running = true
186192

187193
go func() {

0 commit comments

Comments
 (0)