From bc84f83344fdb4966562280345efd604f5da0e4a Mon Sep 17 00:00:00 2001 From: Ce Gao Date: Sat, 22 Oct 2016 11:22:52 +0800 Subject: [PATCH 1/2] fix docker/docker#27484 Signed-off-by: Ce Gao --- libcontainer/configs/validate/validator.go | 28 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libcontainer/configs/validate/validator.go b/libcontainer/configs/validate/validator.go index 448cde27..48d33ff5 100644 --- a/libcontainer/configs/validate/validator.go +++ b/libcontainer/configs/validate/validator.go @@ -125,14 +125,36 @@ func (v *ConfigValidator) sysctl(config *configs.Config) error { } } if strings.HasPrefix(s, "net.") { - if config.Namespaces.Contains(configs.NEWNET) { - continue - } else { + if !config.Namespaces.Contains(configs.NEWNET) { return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", s) } + if path := config.Namespaces.PathOf(configs.NEWNET); path != "" { + if err := checkHostNs(s, path); err != nil { + return err + } + } } return fmt.Errorf("sysctl %q is not in a separate kernel namespace", s) } return nil } + +// checkHostNs checks whether network sysctl is used in host namespace. +func checkHostNs(sysctlConfig string, path string) error { + var currentProcessNetns = "/proc/self/ns/net" + // readlink on the current processes network namespace + destOfCurrentProcess, err := os.Readlink(currentProcessNetns) + if err != nil { + return fmt.Errorf("read soft link %q error", currentProcessNetns) + } + // readlink on the path provided in the struct + destOfContainer, err := os.Readlink(path) + if err != nil { + return fmt.Errorf("read soft link %q error", path) + } + if destOfContainer == destOfCurrentProcess { + return fmt.Errorf("sysctl %q is not allowed in the hosts network namespace", sysctlConfig) + } + return nil +} From 41c35810f2ab71e19f0ed13cbdaf3ff218208ff5 Mon Sep 17 00:00:00 2001 From: Ce Gao Date: Sat, 22 Oct 2016 11:31:15 +0800 Subject: [PATCH 2/2] add test cases about host ns Signed-off-by: Ce Gao --- .../configs/validate/validator_test.go | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/libcontainer/configs/validate/validator_test.go b/libcontainer/configs/validate/validator_test.go index c2100d3c..649e0284 100644 --- a/libcontainer/configs/validate/validator_test.go +++ b/libcontainer/configs/validate/validator_test.go @@ -201,3 +201,38 @@ func TestValidateSysctl(t *testing.T) { } } } + +func TestValidateSysctlWithSameNs(t *testing.T) { + config := &configs.Config{ + Rootfs: "/var", + Sysctl: map[string]string{"net.ctl": "ctl"}, + Namespaces: configs.Namespaces( + []configs.Namespace{ + { + Type: configs.NEWNET, + Path: "/proc/self/ns/net", + }, + }, + ), + } + + validator := validate.New() + err := validator.Validate(config) + if err == nil { + t.Error("Expected error to occur but it was nil") + } +} + +func TestValidateSysctlWithoutNETNamespace(t *testing.T) { + config := &configs.Config{ + Rootfs: "/var", + Sysctl: map[string]string{"net.ctl": "ctl"}, + Namespaces: []configs.Namespace{}, + } + + validator := validate.New() + err := validator.Validate(config) + if err == nil { + t.Error("Expected error to occur but it was nil") + } +}