From 330db60c46dd6acfbcceeeff6260f131ac8255c2 Mon Sep 17 00:00:00 2001 From: mmirecki Date: Thu, 20 Jan 2022 13:53:11 +0100 Subject: [PATCH] Add sysctl whitelist Signed-off-by: Marcin Mirecki --- plugins/meta/tuning/tuning.go | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/plugins/meta/tuning/tuning.go b/plugins/meta/tuning/tuning.go index 0d3e546c7..e6269e0ba 100644 --- a/plugins/meta/tuning/tuning.go +++ b/plugins/meta/tuning/tuning.go @@ -19,12 +19,14 @@ package main import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net" "os" "path" "path/filepath" + "regexp" "strings" "github.com/vishvananda/netlink" @@ -40,6 +42,7 @@ import ( ) const defaultDataDir = "/run/cni/tuning" +const defaultWhitelistFile = "/etc/cni/tuning/whitelist.conf" // TuningConf represents the network tuning configuration. type TuningConf struct { @@ -305,6 +308,10 @@ func cmdAdd(args *skel.CmdArgs) error { return err } + if err = validateConf(tuningConf); err!=nil { + return err + } + // Parse previous result. if tuningConf.RawPrevResult == nil { return fmt.Errorf("Required prevResult missing") @@ -477,3 +484,56 @@ func cmdCheck(args *skel.CmdArgs) error { return nil } + +func validateConf(tuningConf *TuningConf) error { + isPresent, whiteList, err := readWhitelist() + if err != nil { + return err + } + if !isPresent { + return nil + } + for sysctl, _:= range tuningConf.SysCtl { + match, err := contains(sysctl, whiteList) + if err != nil { + return err + } + if !match { + return errors.New(fmt.Sprintf("Sysctl %s is not allowed. Only the following sysctls are allowed: %+v", sysctl, whiteList)) + } + } + return nil +} + +func contains(sysctl string, whiteList []string) (bool, error) { + for _, whiteListElements := range whiteList { + match, err := regexp.MatchString(whiteListElements, sysctl) + if err != nil { + return false, err + } + if match { + return true, nil + } + } + return false, nil +} + +func readWhitelist() (bool,[]string, error) { + if _, err := os.Stat(defaultWhitelistFile); os.IsNotExist(err) { + return false, nil, nil + } + dat, err := os.ReadFile(defaultWhitelistFile) + if err != nil { + return false, nil, err + } + + lines := strings.Split(string(dat), "\n") + whiteList := []string{} + for _, line:= range lines { + line = strings.TrimSpace(line) + if len(line) > 0 { + whiteList = append(whiteList, line) + } + } + return true, whiteList, nil +}