Explorar o código

api/types/container: fix validation for UTSMode, UsernsMode, PidMode

The IPCMode type was added in 497fc8876ede9924f61c0eee4dfadd71e5d9f537, and from
that patch, the intent was to allow `host` (without `:`), `""` (empty, default)
or `container:<container ID>`, but the `Valid()` function seems to be too relaxed
and accepting both `:`, as well as `host:<anything>`. No unit-tests were added
in that patch, and integration-tests only tested for valid values.

Later on, `PidMode`, and `UTSMode` were added in 23feaaa240853c0e7f9817f8c2d272dd1c93ac3f
and f2e5207fc989288ad136d48222df8e7754eb0e9b, both of which were implemented as
a straight copy of the `IPCMode` implementation, copying the same bug.

Finally, commit d4aec5f0a680b6b01bb720830451a93c6ec398e6 implemented unit-tests
for these types, but testing for the wrong behavior of the implementation.

This patch updates the validation to correctly invalidate `host[:<anything>]`
and empty (`:`) types.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn %!s(int64=2) %!d(string=hai) anos
pai
achega
e7d75c8db7
Modificáronse 2 ficheiros con 25 adicións e 32 borrados
  1. 5 28
      api/types/container/hostconfig.go
  2. 20 4
      api/types/container/hostconfig_unix_test.go

+ 5 - 28
api/types/container/hostconfig.go

@@ -175,21 +175,12 @@ func (n UsernsMode) IsHost() bool {
 
 // IsPrivate indicates whether the container uses the a private userns.
 func (n UsernsMode) IsPrivate() bool {
-	return !(n.IsHost())
+	return !n.IsHost()
 }
 
 // Valid indicates whether the userns is valid.
 func (n UsernsMode) Valid() bool {
-	if string(n) == "" {
-		return true
-	}
-
-	switch mode, _, _ := strings.Cut(string(n), ":"); mode {
-	case "host":
-		return true
-	default:
-		return false
-	}
+	return n == "" || n.IsHost()
 }
 
 // CgroupSpec represents the cgroup to use for the container.
@@ -217,7 +208,7 @@ type UTSMode string
 
 // IsPrivate indicates whether the container uses its private UTS namespace.
 func (n UTSMode) IsPrivate() bool {
-	return !(n.IsHost())
+	return !n.IsHost()
 }
 
 // IsHost indicates whether the container uses the host's UTS namespace.
@@ -227,13 +218,7 @@ func (n UTSMode) IsHost() bool {
 
 // Valid indicates whether the UTS namespace is valid.
 func (n UTSMode) Valid() bool {
-	parts := strings.Split(string(n), ":")
-	switch mode := parts[0]; mode {
-	case "", "host":
-	default:
-		return false
-	}
-	return true
+	return n == "" || n.IsHost()
 }
 
 // PidMode represents the pid namespace of the container.
@@ -257,15 +242,7 @@ func (n PidMode) IsContainer() bool {
 
 // Valid indicates whether the pid namespace is valid.
 func (n PidMode) Valid() bool {
-	mode, v, ok := strings.Cut(string(n), ":")
-	switch mode {
-	case "", "host":
-		return true
-	case "container":
-		return ok && v != ""
-	default:
-		return false
-	}
+	return n == "" || n.IsHost() || n.IsContainer()
 }
 
 // Container returns the name of the container whose pid namespace is going to be used.

+ 20 - 4
api/types/container/hostconfig_unix_test.go

@@ -15,7 +15,10 @@ func TestCgroupnsMode(t *testing.T) {
 		"":                {private: false, host: false, empty: true, valid: true},
 		"something:weird": {private: false, host: false, empty: false, valid: false},
 		"host":            {private: false, host: true, empty: false, valid: true},
-		"host:name":       {private: false, host: false, empty: false, valid: false},
+		"host:":           {valid: false},
+		"host:name":       {valid: false},
+		":name":           {valid: false},
+		":":               {valid: false},
 		"private":         {private: true, host: false, empty: false, valid: true},
 		"private:name":    {private: false, host: false, empty: false, valid: false},
 	}
@@ -70,6 +73,10 @@ func TestIpcMode(t *testing.T) {
 		"something:weird":       {},
 		":weird":                {},
 		"host":                  {host: true, valid: true},
+		"host:":                 {valid: false},
+		"host:name":             {valid: false},
+		":name":                 {valid: false},
+		":":                     {valid: false},
 		"container":             {},
 		"container:":            {container: true, valid: true, ctrName: ""},
 		"container:name":        {container: true, valid: true, ctrName: "name"},
@@ -94,7 +101,10 @@ func TestUTSMode(t *testing.T) {
 		"":                {private: true, host: false, valid: true},
 		"something:weird": {private: true, host: false, valid: false},
 		"host":            {private: false, host: true, valid: true},
-		"host:name":       {private: true, host: false, valid: true},
+		"host:":           {private: true, valid: false},
+		"host:name":       {private: true, valid: false},
+		":name":           {private: true, valid: false},
+		":":               {private: true, valid: false},
 	}
 	for mode, expected := range modes {
 		t.Run("mode="+string(mode), func(t *testing.T) {
@@ -111,7 +121,10 @@ func TestUsernsMode(t *testing.T) {
 		"":                {private: true, host: false, valid: true},
 		"something:weird": {private: true, host: false, valid: false},
 		"host":            {private: false, host: true, valid: true},
-		"host:name":       {private: true, host: false, valid: true},
+		"host:":           {private: true, valid: false},
+		"host:name":       {private: true, valid: false},
+		":name":           {private: true, valid: false},
+		":":               {private: true, valid: false},
 	}
 	for mode, expected := range modes {
 		t.Run("mode="+string(mode), func(t *testing.T) {
@@ -127,7 +140,10 @@ func TestPidMode(t *testing.T) {
 		"":                {private: true, host: false, valid: true},
 		"something:weird": {private: true, host: false, valid: false},
 		"host":            {private: false, host: true, valid: true},
-		"host:name":       {private: true, host: false, valid: true},
+		"host:":           {private: true, valid: false},
+		"host:name":       {private: true, valid: false},
+		":name":           {private: true, valid: false},
+		":":               {private: true, valid: false},
 	}
 	for mode, expected := range modes {
 		t.Run("mode="+string(mode), func(t *testing.T) {