Skip to content

Commit 7ca247e

Browse files
author
s00613818
committed
fix 714-plugin add netns validation reinforcement
Signed-off-by: Poor12 <[email protected]>
1 parent 54f1587 commit 7ca247e

File tree

6 files changed

+121
-13
lines changed

6 files changed

+121
-13
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ go 1.14
55
require (
66
github.com/onsi/ginkgo/v2 v2.1.3
77
github.com/onsi/gomega v1.17.0
8+
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f
9+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da
810
)

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl
4141
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4242
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4343
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
44+
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
45+
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
4446
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
4547
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4648
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -63,6 +65,7 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
6365
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6466
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6567
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
68+
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6669
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6770
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6871
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pkg/ns/ns_linux.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2022 CNI authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package ns
16+
17+
import (
18+
"runtime"
19+
20+
"github.com/containernetworking/cni/pkg/types"
21+
"github.com/vishvananda/netns"
22+
)
23+
24+
// Returns an object representing the current OS thread's network namespace
25+
func getCurrentNS() (netns.NsHandle, error) {
26+
// Lock the thread in case other goroutine executes in it and changes its
27+
// network namespace after getCurrentThreadNetNSPath(), otherwise it might
28+
// return an unexpected network namespace.
29+
runtime.LockOSThread()
30+
defer runtime.UnlockOSThread()
31+
return netns.Get()
32+
}
33+
34+
func CheckNetNS(nsPath string) (bool, *types.Error) {
35+
ns, err := netns.GetFromPath(nsPath)
36+
// Let plugins check whether nsPath from args is valid. Also support CNI DEL for empty nsPath as already-deleted nsPath.
37+
if err != nil {
38+
return false, nil
39+
}
40+
defer ns.Close()
41+
42+
pluginNS, err := getCurrentNS()
43+
if err != nil {
44+
return false, types.NewError(types.ErrInvalidNetNS, "get plugin's netns failed", "")
45+
}
46+
defer pluginNS.Close()
47+
48+
return pluginNS.Equal(ns), nil
49+
}

pkg/ns/ns_windows.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2022 CNI authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package ns
16+
17+
func CheckNetNS(nsPath string) (bool, *types.Error) {
18+
return false, nil
19+
}

pkg/skel/skel.go

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"os"
2727
"strings"
2828

29+
"github.com/containernetworking/cni/pkg/ns"
2930
"github.com/containernetworking/cni/pkg/types"
3031
"github.com/containernetworking/cni/pkg/utils"
3132
"github.com/containernetworking/cni/pkg/version"
@@ -34,12 +35,13 @@ import (
3435
// CmdArgs captures all the arguments passed in to the plugin
3536
// via both env vars and stdin
3637
type CmdArgs struct {
37-
ContainerID string
38-
Netns string
39-
IfName string
40-
Args string
41-
Path string
42-
StdinData []byte
38+
ContainerID string
39+
Netns string
40+
IfName string
41+
Args string
42+
Path string
43+
NetnsOverride string
44+
StdinData []byte
4345
}
4446

4547
type dispatcher struct {
@@ -55,7 +57,7 @@ type dispatcher struct {
5557
type reqForCmdEntry map[string]bool
5658

5759
func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
58-
var cmd, contID, netns, ifName, args, path string
60+
var cmd, contID, netns, ifName, args, path, netnsOverride string
5961

6062
vars := []struct {
6163
name string
@@ -116,6 +118,15 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
116118
"DEL": true,
117119
},
118120
},
121+
{
122+
"CNI_NETNS_OVERRIDE",
123+
&netnsOverride,
124+
reqForCmdEntry{
125+
"ADD": false,
126+
"CHECK": false,
127+
"DEL": false,
128+
},
129+
},
119130
}
120131

121132
argsMissing := make([]string, 0)
@@ -143,12 +154,13 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
143154
}
144155

145156
cmdArgs := &CmdArgs{
146-
ContainerID: contID,
147-
Netns: netns,
148-
IfName: ifName,
149-
Args: args,
150-
Path: path,
151-
StdinData: stdinData,
157+
ContainerID: contID,
158+
Netns: netns,
159+
IfName: ifName,
160+
Args: args,
161+
Path: path,
162+
StdinData: stdinData,
163+
NetnsOverride: netnsOverride,
152164
}
153165
return cmd, cmdArgs, nil
154166
}
@@ -217,6 +229,17 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
217229
switch cmd {
218230
case "ADD":
219231
err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdAdd)
232+
if err != nil {
233+
return err
234+
}
235+
if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" || cmdArgs.NetnsOverride != "1" {
236+
isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns)
237+
if checkErr != nil {
238+
return checkErr
239+
} else if isPluginNetNS {
240+
return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "")
241+
}
242+
}
220243
case "CHECK":
221244
configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
222245
if err != nil {
@@ -241,6 +264,17 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
241264
return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow CHECK", "")
242265
case "DEL":
243266
err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel)
267+
if err != nil {
268+
return err
269+
}
270+
if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" || cmdArgs.NetnsOverride != "1" {
271+
isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns)
272+
if checkErr != nil {
273+
return checkErr
274+
} else if isPluginNetNS {
275+
return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "")
276+
}
277+
}
244278
case "VERSION":
245279
if err := versionInfo.Encode(t.Stdout); err != nil {
246280
return types.NewError(types.ErrIOFailure, err.Error(), "")

pkg/types/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ const (
165165
ErrIOFailure // 5
166166
ErrDecodingFailure // 6
167167
ErrInvalidNetworkConfig // 7
168+
ErrInvalidNetNS // 8
168169
ErrTryAgainLater uint = 11
169170
ErrInternal uint = 999
170171
)

0 commit comments

Comments
 (0)