All of lore.kernel.org
 help / color / mirror / Atom feed
* [meta-virtualization][scarthgap][PATCH 1/2] docker-moby: Fix CVE-2026-33997
@ 2026-05-13 15:09 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
  2026-05-13 15:10 ` [meta-virtualization][scarthgap][PATCH 2/2] docker-moby: Fix CVE-2026-34040 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
  0 siblings, 1 reply; 3+ messages in thread
From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-05-13 15:09 UTC (permalink / raw)
  To: meta-virtualization

From: Deepak Rathore <deeratho@cisco.com>

Pick the version-specific cherry-pick [1] of the upstream fix [2] mentioned in [3].

[1] https://github.com/moby/moby/commit/d5986c0430124d82ce87b439638d8ebb16916e40
[2] https://github.com/moby/moby/commit/99a095ecf04e8849318f2811bb3f687905eab09b
[3] https://security-tracker.debian.org/tracker/CVE-2026-33997

Signed-off-by: Deepak Rathore <deeratho@cisco.com>

diff --git a/recipes-containers/docker/docker-moby_git.bb b/recipes-containers/docker/docker-moby_git.bb
index e66416db..26dce276 100644
--- a/recipes-containers/docker/docker-moby_git.bb
+++ b/recipes-containers/docker/docker-moby_git.bb
@@ -56,6 +56,7 @@ SRC_URI = "\
 	file://0001-libnetwork-use-GO-instead-of-go.patch \
         file://0001-cli-use-external-GO111MODULE-and-cross-compiler.patch \
         file://0001-dynbinary-use-go-cross-compiler.patch;patchdir=src/import \
+		file://CVE-2026-33997.patch;patchdir=src/import \
 	"
 
 DOCKER_COMMIT = "${SRCREV_moby}"
diff --git a/recipes-containers/docker/files/CVE-2026-33997.patch b/recipes-containers/docker/files/CVE-2026-33997.patch
new file mode 100644
index 00000000..9da4b3cf
--- /dev/null
+++ b/recipes-containers/docker/files/CVE-2026-33997.patch
@@ -0,0 +1,179 @@
+From 7e35ad066ee0c89e15fca9e9b95933b79ba315b7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
+Date: Thu, 19 Mar 2026 19:18:23 +0100
+Subject: [PATCH] plugin: Fix off-by-one in privilege validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fix an off-by-one error in isEqual() where the comparison loop started
+at index 1 instead of 0, causing the first privilege (after sorting
+alphabetically by name) to never be validated.
+
+This allowed a malicious plugin to request different values for
+whichever privilege sorts first — most notably "allow-all-devices",
+which grants unrestricted rwm access to all host devices.
+
+The bug also meant that plugins requesting exactly one privilege had
+zero iterations of the comparison loop, bypassing validation entirely.
+
+Also fix an existing test case ("diff-order-but-same-value") that only
+passed due to the off-by-one bug, and add test cases for single-element
+and first-sorted-element mismatches.
+
+CVE: CVE-2026-33997
+Upstream-Status: Backport [https://github.com/moby/moby/commit/d5986c0430124d82ce87b439638d8ebb16916e40]
+
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit 99a095ecf04e8849318f2811bb3f687905eab09b)
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit d5986c0430124d82ce87b439638d8ebb16916e40)
+Signed-off-by: Deepak Rathore <deeratho@cisco.com>
+---
+ plugin/manager.go      | 50 ++++++++++++++++++++++++------------------
+ plugin/manager_test.go | 44 +++++++++++++++++++++++++++++++++----
+ 2 files changed, 69 insertions(+), 25 deletions(-)
+
+diff --git a/plugin/manager.go b/plugin/manager.go
+index 81f3d67b80..d98b968c7d 100644
+--- a/plugin/manager.go
++++ b/plugin/manager.go
+@@ -1,14 +1,14 @@
+ package plugin // import "github.com/docker/docker/plugin"
+ 
+ import (
++	"cmp"
+ 	"context"
+ 	"encoding/json"
+ 	"io"
+ 	"os"
+ 	"path/filepath"
+-	"reflect"
+ 	"regexp"
+-	"sort"
++	"slices"
+ 	"strings"
+ 	"sync"
+ 	"syscall"
+@@ -331,34 +331,42 @@ func makeLoggerStreams(id string) (stdout, stderr io.WriteCloser) {
+ }
+ 
+ func validatePrivileges(requiredPrivileges, privileges types.PluginPrivileges) error {
+-	if !isEqual(requiredPrivileges, privileges, isEqualPrivilege) {
++	if len(requiredPrivileges) != len(privileges) {
+ 		return errors.New("incorrect privileges")
+ 	}
+ 
+-	return nil
+-}
+-
+-func isEqual(arrOne, arrOther types.PluginPrivileges, compare func(x, y types.PluginPrivilege) bool) bool {
+-	if len(arrOne) != len(arrOther) {
+-		return false
+-	}
+-
+-	sort.Sort(arrOne)
+-	sort.Sort(arrOther)
++	a := normalizePrivileges(requiredPrivileges)
++	b := normalizePrivileges(privileges)
+ 
+-	for i := 1; i < arrOne.Len(); i++ {
+-		if !compare(arrOne[i], arrOther[i]) {
+-			return false
++	for i := range a {
++		if a[i].Name != b[i].Name {
++			return errors.New("incorrect privileges")
++		}
++		if !slices.Equal(a[i].Value, b[i].Value) {
++			return errors.New("incorrect privileges")
+ 		}
+ 	}
+ 
+-	return true
++	return nil
+ }
+ 
+-func isEqualPrivilege(a, b types.PluginPrivilege) bool {
+-	if a.Name != b.Name {
+-		return false
++// normalizePrivileges returns a normalized copy of privileges with privilege names
++// and each privilege's values sorted for order-insensitive comparison.
++// The input is not mutated.
++func normalizePrivileges(privileges types.PluginPrivileges) types.PluginPrivileges {
++	normalized := make(types.PluginPrivileges, len(privileges))
++	for i, privilege := range privileges {
++		normalized[i] = types.PluginPrivilege{
++			Name:        privilege.Name,
++			Description: privilege.Description,
++			Value:       slices.Clone(privilege.Value),
++		}
++		slices.Sort(normalized[i].Value)
+ 	}
+ 
+-	return reflect.DeepEqual(a.Value, b.Value)
++	slices.SortFunc(normalized, func(a, b types.PluginPrivilege) int {
++		return cmp.Compare(a.Name, b.Name)
++	})
++
++	return normalized
+ }
+diff --git a/plugin/manager_test.go b/plugin/manager_test.go
+index 62ccf2149d..6d58865044 100644
+--- a/plugin/manager_test.go
++++ b/plugin/manager_test.go
+@@ -44,12 +44,48 @@ func TestValidatePrivileges(t *testing.T) {
+ 			},
+ 			result: true,
+ 		},
++		"single-element-same": {
++			requiredPrivileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"true"}},
++			},
++			privileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"true"}},
++			},
++			result: true,
++		},
++		"single-element-diff-value": {
++			requiredPrivileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"false"}},
++			},
++			privileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"true"}},
++			},
++			result: false,
++		},
++		"first-sorted-element-diff-value": {
++			requiredPrivileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"false"}},
++				{Name: "network", Description: "Description", Value: []string{"host"}},
++			},
++			privileges: []types.PluginPrivilege{
++				{Name: "allow-all-devices", Description: "Description", Value: []string{"true"}},
++				{Name: "network", Description: "Description", Value: []string{"host"}},
++			},
++			result: false,
++		},
++		"empty-privileges": {
++			requiredPrivileges: []types.PluginPrivilege{},
++			privileges:         []types.PluginPrivilege{},
++			result:             true,
++		},
+ 	}
+ 
+ 	for key, data := range testData {
+-		err := validatePrivileges(data.requiredPrivileges, data.privileges)
+-		if (err == nil) != data.result {
+-			t.Fatalf("Test item %s expected result to be %t, got %t", key, data.result, (err == nil))
+-		}
++		t.Run(key, func(t *testing.T) {
++			err := validatePrivileges(data.requiredPrivileges, data.privileges)
++			if (err == nil) != data.result {
++				t.Fatalf("expected result to be %t, got %t", data.result, (err == nil))
++			}
++		})
+ 	}
+ }
+-- 
+2.44.4
+
-- 
2.35.6



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-28  3:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 15:09 [meta-virtualization][scarthgap][PATCH 1/2] docker-moby: Fix CVE-2026-33997 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-05-13 15:10 ` [meta-virtualization][scarthgap][PATCH 2/2] docker-moby: Fix CVE-2026-34040 Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-05-28  3:03   ` Bruce Ashfield

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.