From 7c452c77cd7dadf36dcc565f4b298afa80300c5e Mon Sep 17 00:00:00 2001 From: mmirecki Date: Fri, 15 Apr 2022 15:06:47 +0200 Subject: [PATCH] Check for duplicated sysctl keys Signed-off-by: mmirecki --- plugins/meta/tuning/tuning.go | 28 +++++++++++++++++ plugins/meta/tuning/tuning_test.go | 49 ++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/plugins/meta/tuning/tuning.go b/plugins/meta/tuning/tuning.go index 99c191aa0..719e4ce74 100644 --- a/plugins/meta/tuning/tuning.go +++ b/plugins/meta/tuning/tuning.go @@ -304,6 +304,9 @@ func restoreBackup(ifName, containerID, backupPath string) error { } func cmdAdd(args *skel.CmdArgs) error { + if err := validateSysctlConflictingKeys(args.StdinData); err != nil { + return err + } tuningConf, err := parseConf(args.StdinData, args.Args) if err != nil { return err @@ -405,6 +408,9 @@ func main() { } func cmdCheck(args *skel.CmdArgs) error { + if err := validateSysctlConflictingKeys(args.StdinData); err != nil { + return err + } tuningConf, err := parseConf(args.StdinData, args.Args) if err != nil { return err @@ -542,3 +548,25 @@ func readAllowlist() (bool, []string, error) { } return true, allowList, nil } + +type sysctlKey string + +type sysctlCheck struct { + SysCtl map[sysctlKey]string `json:"sysctl"` +} + +var sysctlDuplicatesMap = map[sysctlKey]interface{}{} + +func (d *sysctlKey) UnmarshalText(data []byte) error { + key := sysctlKey(string(data)) + if _, exists := sysctlDuplicatesMap[key]; exists { + return errors.New("duplicated sysctl keys are not allowed") + } + sysctlDuplicatesMap[key] = "" + return nil +} + +func validateSysctlConflictingKeys(data []byte) error { + sysctlCheck := sysctlCheck{} + return json.Unmarshal(data, &sysctlCheck) +} diff --git a/plugins/meta/tuning/tuning_test.go b/plugins/meta/tuning/tuning_test.go index b2ad5f33d..e8f064251 100644 --- a/plugins/meta/tuning/tuning_test.go +++ b/plugins/meta/tuning/tuning_test.go @@ -130,6 +130,7 @@ var _ = Describe("tuning plugin", func() { return nil }) Expect(err).NotTo(HaveOccurred()) + sysctlDuplicatesMap = map[sysctlKey]interface{}{} }) AfterEach(func() { @@ -1122,5 +1123,53 @@ var _ = Describe("tuning plugin", func() { }) Expect(err).NotTo(HaveOccurred()) }) + + It(fmt.Sprintf("[%s] does not allow duplicated sysctl values", ver), func() { + conf := []byte(fmt.Sprintf(`{ + "name": "test", + "type": "tuning", + "cniVersion": "%s", + "sysctl": { + "net.ipv4.conf.all.log_martians": "1", + "net.ipv4.conf.all.log_martians": "0" + }, + "prevResult": { + "interfaces": [ + {"name": "dummy0", "sandbox":"netns"} + ], + "ips": [ + { + "version": "4", + "address": "10.0.0.2/24", + "gateway": "10.0.0.1", + "interface": 0 + } + ] + } + }`, ver)) + + args := &skel.CmdArgs{ + ContainerID: "dummy", + Netns: targetNS.Path(), + IfName: IFNAME, + StdinData: conf, + } + + beforeConf = configToRestore{} + + err := originalNS.Do(func(ns.NetNS) error { + defer GinkgoRecover() + + _, _, err := testutils.CmdAddWithArgs(args, func() error { + return cmdAdd(args) + }) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("duplicated")) + + return nil + }) + Expect(err).NotTo(HaveOccurred()) + }) + } })