kata-containers/runtime/patches/0027-network-add-more-strict-check-for-input-network-inte.patch
holyfei c709612f2a kata-containers: modify kata-containers version
Fix #I4KI81
reason: modify kata-containers version and update
it to 1.11.1

Signed-off-by: holyfei <yangfeiyu20092010@163.com>
2021-11-30 20:08:25 +08:00

183 lines
5.0 KiB
Diff

From ec15337fc816767ca0e8183576405499080b9b1e Mon Sep 17 00:00:00 2001
From: jiangpengfei <jiangpengfei9@huawei.com>
Date: Sun, 16 Aug 2020 16:41:18 +0800
Subject: [PATCH 27/50] network: add more strict check for input network
interface
reason: kata-network add-iface command will receive the network
interface info from untrust user, so we need to add more strict
check for input network interface info.
Signed-off-by: jiangpengfei <jiangpengfei9@huawei.com>
---
virtcontainers/network.go | 117 ++++++++++++++++++++++++++++++++++++++++++++++
virtcontainers/sandbox.go | 11 +++++
2 files changed, 128 insertions(+)
diff --git a/virtcontainers/network.go b/virtcontainers/network.go
index db235cf6..a1676ccd 100644
--- a/virtcontainers/network.go
+++ b/virtcontainers/network.go
@@ -13,8 +13,10 @@ import (
"math/rand"
"net"
"os"
+ "regexp"
"runtime"
"sort"
+ "strings"
"time"
"github.com/containernetworking/plugins/pkg/ns"
@@ -55,6 +57,17 @@ const (
NetXConnectInvalidModel
)
+const (
+ maxIPAddrLen = 18
+ maxInterfaceLen = 15
+ minMTUVal = 46
+ maxMTUVal = 9600
+)
+
+var (
+ regInfName = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_\-.]*$`)
+)
+
//IsValid checks if a model is valid
func (n NetInterworkingModel) IsValid() bool {
return 0 <= int(n) && int(n) < int(NetXConnectInvalidModel)
@@ -1368,3 +1381,107 @@ func convertToCompatInterfaces(es *[]Endpoint) []*vcTypes.Interface {
return infs
}
+
+// verifyInterfaceName verifies the interface name valid or not
+func verifyInterfaceName(name string) error {
+ // verify `Name` before `Tapname` because of the strict rules
+ name = strings.TrimSpace(name)
+ if len(name) > maxInterfaceLen {
+ return fmt.Errorf("interface name can't be longer than 15")
+ } else if len(name) == 0 || name == "\n" {
+ return fmt.Errorf("interface name can't be empty")
+ }
+
+ // QMP rules of `Name`
+ chk := regInfName.FindAllString(name, -1)
+ if chk == nil {
+ return fmt.Errorf("invalid input of interface name, please check the rules")
+ }
+
+ return nil
+}
+
+// verifyIPAndMask verifies CIDR notation IP address and mask like "192.0.2.0/24"
+func verifyIPAndMask(ip string) (nlIpMask *net.IPNet, err error) {
+ ip = strings.TrimSpace(ip)
+
+ if len(ip) > maxIPAddrLen {
+ return nil, fmt.Errorf("the length of IP address is too long, max ip len :%d", maxIPAddrLen)
+ }
+
+ if nlIpMask, err = netlink.ParseIPNet(ip); err != nil {
+ return nil, fmt.Errorf("invalid input of IP : %v", err)
+ }
+
+ return nlIpMask, nil
+}
+
+// verifyMac verifies MAC address
+func verifyMac(mac string) error {
+ mac = strings.TrimSpace(mac)
+ if _, err := net.ParseMAC(mac); err != nil {
+ return fmt.Errorf("invalid input of Mac : %v", err)
+ }
+
+ return nil
+}
+
+// verifyMtu verifies MTU value of interface
+func verifyMtu(mtu uint64) error {
+ if mtu < minMTUVal || mtu > maxMTUVal {
+ return fmt.Errorf("invalid input of MTU : %v", mtu)
+ }
+ return nil
+}
+
+// verifyIP verifies the IP address
+func verifyIP(ip string) (*net.IP, error) {
+ ip = strings.TrimSpace(ip)
+
+ if len(ip) > maxIPAddrLen {
+ return nil, fmt.Errorf("the length of IP address is too long, max ip len :%d", maxIPAddrLen)
+ }
+
+ var netIP net.IP
+ if netIP = net.ParseIP(ip); netIP == nil {
+ return nil, fmt.Errorf("invalid IP: %s", ip)
+ }
+
+ return &netIP, nil
+}
+
+// validInterface check the input interface valid or not
+func validInterface(inf *vcTypes.Interface, enableCompatOldCNI bool) error {
+ if enableCompatOldCNI && verifyInterfaceName(inf.Device) != nil {
+ return fmt.Errorf("device name should not be empty when enable_compat_old_cni config enabled")
+ }
+
+ if inf.Name == "" || inf.Mtu == 0 || inf.HwAddr == "" {
+ return fmt.Errorf("name/mtu/hwaddr of interface must be specified")
+ }
+
+ if err := verifyInterfaceName(inf.Name); err != nil {
+ return err
+ }
+
+ if err := verifyMac(inf.HwAddr); err != nil {
+ return err
+ }
+
+ if err := verifyMtu(inf.Mtu); err != nil {
+ return err
+ }
+
+ // Currently, only one IP address can be passed, which reduces the test entry and fault injection.
+ if len(inf.IPAddresses) > 0 {
+ if len(inf.IPAddresses) != 1 {
+ return fmt.Errorf("only one IP address is supported currently")
+ }
+ _, err := verifyIP(inf.IPAddresses[0].Address)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go
index 6a643a12..f6826812 100644
--- a/virtcontainers/sandbox.go
+++ b/virtcontainers/sandbox.go
@@ -952,6 +952,17 @@ func (s *Sandbox) generateNetInfo(inf *vcTypes.Interface) (NetworkInfo, error) {
// AddInterface adds new nic to the sandbox.
func (s *Sandbox) AddInterface(inf *vcTypes.Interface) (grpcIf *vcTypes.Interface, err error) {
+ err = validInterface(inf, s.config.NetworkConfig.EnableCompatOldCNI)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, ep := range s.networkNS.Endpoints {
+ if ep.Name() == inf.Name {
+ return nil, fmt.Errorf("interface %s is already exist", inf.Name)
+ }
+ }
+
netInfo, err := s.generateNetInfo(inf)
if err != nil {
return nil, err
--
2.14.3 (Apple Git-98)