* [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
* [meta-virtualization][scarthgap][PATCH 2/2] docker-moby: Fix CVE-2026-34040
@ 2026-05-13 15:10 ` Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)
2026-05-28 3:03 ` Bruce Ashfield
0 siblings, 1 reply; 3+ messages in thread
From: Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco) @ 2026-05-13 15:10 UTC (permalink / raw)
To: meta-virtualization
From: Deepak Rathore <deeratho@cisco.com>
The upstream fix [3] & [4] referenced in the Debian security
advisory [5] is present in the v25.0 branch, which aligns with the
scarthgap branch so pick the corresponding commit [1] & [2] to apply
the CVE fix.
[1] https://github.com/moby/moby/commit/553e8214614ee0d65ee309f148a8e865634cc291
[2] https://github.com/moby/moby/commit/4d0135c2d25b89ecc62a15277f20177150195695
[3] https://github.com/moby/moby/commit/6d311e0d8d4174a6347942db78c553fb7dc3762e
[4] https://github.com/moby/moby/commit/db7dadaca041953430d1e2144088c311b78b96d7
[5] https://security-tracker.debian.org/tracker/CVE-2026-34040
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 26dce276..eb493a43 100644
--- a/recipes-containers/docker/docker-moby_git.bb
+++ b/recipes-containers/docker/docker-moby_git.bb
@@ -57,6 +57,8 @@ SRC_URI = "\
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 \
+ file://CVE-2026-34040_p1.patch;patchdir=src/import \
+ file://CVE-2026-34040_p2.patch;patchdir=src/import \
"
DOCKER_COMMIT = "${SRCREV_moby}"
diff --git a/recipes-containers/docker/files/CVE-2026-34040_p1.patch b/recipes-containers/docker/files/CVE-2026-34040_p1.patch
new file mode 100644
index 00000000..9fb96ab0
--- /dev/null
+++ b/recipes-containers/docker/files/CVE-2026-34040_p1.patch
@@ -0,0 +1,215 @@
+From b2ff8a60155731641418d1a8b9efaf9e044e1971 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
+Date: Mon, 16 Feb 2026 14:15:24 +0100
+Subject: [PATCH 1/2] pkg/authz: Reject requests exceeding body size limit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously, the authorization system would silently skip body inspection when
+request bodies exceeded the maximum size limit (1MiB).
+
+The authorization plugins would receive an empty body for inspection
+while the actual large payload would still be processed by the Docker
+daemon, allowing malicious requests to circumvent plugin-based security
+controls.
+
+CVE: CVE-2026-34040
+Upstream-Status: Backport [https://github.com/moby/moby/commit/553e8214614ee0d65ee309f148a8e865634cc291]
+
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit 7a767b27fd1238c89a5cc926c39e27d3bcf58e35)
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit 553e8214614ee0d65ee309f148a8e865634cc291)
+Signed-off-by: Deepak Rathore <deeratho@cisco.com>
+---
+ pkg/authorization/authz.go | 56 ++++++-----------
+ pkg/authorization/authz_unix_test.go | 93 +++++++++++++++++++---------
+ 2 files changed, 83 insertions(+), 66 deletions(-)
+
+diff --git a/pkg/authorization/authz.go b/pkg/authorization/authz.go
+index d568a2b597..3bc30f61cf 100644
+--- a/pkg/authorization/authz.go
++++ b/pkg/authorization/authz.go
+@@ -55,28 +55,31 @@ type Ctx struct {
+ authReq *Request
+ }
+
+-func isChunked(r *http.Request) bool {
+- // RFC 7230 specifies that content length is to be ignored if Transfer-Encoding is chunked
+- if strings.EqualFold(r.Header.Get("Transfer-Encoding"), "chunked") {
+- return true
+- }
+- for _, v := range r.TransferEncoding {
+- if strings.EqualFold(v, "chunked") {
+- return true
+- }
+- }
+- return false
+-}
+-
+ // AuthZRequest authorized the request to the docker daemon using authZ plugins
+ func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
+ var body []byte
+- if sendBody(ctx.requestURI, r.Header) && (r.ContentLength > 0 || isChunked(r)) && r.ContentLength < maxBodySize {
+- var err error
+- body, r.Body, err = drainBody(r.Body)
+- if err != nil {
++ if sendBody(ctx.requestURI, r.Header) {
++ // Wrap the original request body in a buffered reader so we can inspect
++ // the prefix without consuming bytes from the downstream reader.
++ // `Peek(maxBodySize + 1)` is used as a size check:
++ // - err == nil means at least maxBodySize+1 bytes are buffered/available,
++ // so the payload exceeds the plugin limit and is rejected.
++ // - otherwise, `peeked` contains the complete body bytes currently available
++ // (for short bodies this is the full payload), and reads from r.Body still
++ // stream the original body unchanged.
++ bufBody := bufio.NewReaderSize(r.Body, maxBodySize+1)
++ r.Body = ioutils.NewReadCloserWrapper(bufBody, r.Body.Close)
++
++ peeked, err := bufBody.Peek(maxBodySize + 1)
++ if err == nil {
++ // Successfully peeked maxBodySize+1 bytes, so body is too large
++ // TODO: Allows plugin to opt in
++ return fmt.Errorf("request body too large for authorization plugin: size exceeds %d bytes", maxBodySize)
++ } else if err != io.EOF {
+ return err
+ }
++
++ body = peeked
+ }
+
+ var h bytes.Buffer
+@@ -142,25 +145,6 @@ func (ctx *Ctx) AuthZResponse(rm ResponseModifier, r *http.Request) error {
+ return nil
+ }
+
+-// drainBody dump the body (if its length is less than 1MB) without modifying the request state
+-func drainBody(body io.ReadCloser) ([]byte, io.ReadCloser, error) {
+- bufReader := bufio.NewReaderSize(body, maxBodySize)
+- newBody := ioutils.NewReadCloserWrapper(bufReader, func() error { return body.Close() })
+-
+- data, err := bufReader.Peek(maxBodySize)
+- // Body size exceeds max body size
+- if err == nil {
+- log.G(context.TODO()).Warnf("Request body is larger than: '%d' skipping body", maxBodySize)
+- return nil, newBody, nil
+- }
+- // Body size is less than maximum size
+- if err == io.EOF {
+- return data, newBody, nil
+- }
+- // Unknown error
+- return nil, newBody, err
+-}
+-
+ func isAuthEndpoint(urlPath string) (bool, error) {
+ // eg www.test.com/v1.24/auth/optional?optional1=something&optional2=something (version optional)
+ matched, err := regexp.MatchString(`^[^\/]*\/(v\d[\d\.]*\/)?auth.*`, urlPath)
+diff --git a/pkg/authorization/authz_unix_test.go b/pkg/authorization/authz_unix_test.go
+index 66b4d20452..c726e5f79a 100644
+--- a/pkg/authorization/authz_unix_test.go
++++ b/pkg/authorization/authz_unix_test.go
+@@ -139,36 +139,69 @@ func TestResponseModifier(t *testing.T) {
+ }
+ }
+
+-func TestDrainBody(t *testing.T) {
+- tests := []struct {
+- length int // length is the message length send to drainBody
+- expectedBodyLength int // expectedBodyLength is the expected body length after drainBody is called
+- }{
+- {10, 10}, // Small message size
+- {maxBodySize - 1, maxBodySize - 1}, // Max message size
+- {maxBodySize * 2, 0}, // Large message size (skip copying body)
+-
+- }
+-
+- for _, test := range tests {
+- msg := strings.Repeat("a", test.length)
+- body, closer, err := drainBody(io.NopCloser(bytes.NewReader([]byte(msg))))
+- if err != nil {
+- t.Fatal(err)
+- }
+- if len(body) != test.expectedBodyLength {
+- t.Fatalf("Body must be copied, actual length: '%d'", len(body))
+- }
+- if closer == nil {
+- t.Fatal("Closer must not be nil")
+- }
+- modified, err := io.ReadAll(closer)
+- if err != nil {
+- t.Fatalf("Error must not be nil: '%v'", err)
+- }
+- if len(modified) != len(msg) {
+- t.Fatalf("Result should not be truncated. Original length: '%d', new length: '%d'", len(msg), len(modified))
+- }
++type recordingPlugin struct {
++ recordedRequest Request
++}
++
++func (p *recordingPlugin) Name() string { return "recording-plugin" }
++
++func (p *recordingPlugin) AuthZRequest(authReq *Request) (*Response, error) {
++ p.recordedRequest = *authReq
++ p.recordedRequest.RequestBody = bytes.Clone(authReq.RequestBody)
++ return &Response{Allow: true}, nil
++}
++
++func (p *recordingPlugin) AuthZResponse(_ *Request) (*Response, error) {
++ return &Response{Allow: true}, nil
++}
++
++func TestAuthZRequestBodyWithinLimit(t *testing.T) {
++ payload := strings.Repeat("a", maxBodySize)
++ plugin := &recordingPlugin{}
++ ctx := NewCtx([]Plugin{plugin}, "user", "tls", http.MethodPost, "/containers/create")
++
++ req := httptest.NewRequest(http.MethodPost, "http://example.com/containers/create", strings.NewReader(payload))
++ req.Header.Set("Content-Type", "application/json")
++
++ if err := ctx.AuthZRequest(httptest.NewRecorder(), req); err != nil {
++ t.Fatalf("AuthZRequest failed: %v", err)
++ }
++
++ if string(plugin.recordedRequest.RequestBody) != payload {
++ t.Fatalf("expected full request body to be sent to plugin, got length %d, expected %d", len(plugin.recordedRequest.RequestBody), len(payload))
++ }
++
++ remaining, err := io.ReadAll(req.Body)
++ if err != nil {
++ t.Fatalf("failed to read request body after authz: %v", err)
++ }
++ if string(remaining) != payload {
++ t.Fatalf("request body should be preserved for downstream readers")
++ }
++}
++
++func TestAuthZRequestBodyOverLimit(t *testing.T) {
++ payload := strings.Repeat("a", maxBodySize+1)
++ plugin := &recordingPlugin{}
++ ctx := NewCtx([]Plugin{plugin}, "user", "tls", http.MethodPost, "/containers/create")
++
++ req := httptest.NewRequest(http.MethodPost, "http://example.com/containers/create", strings.NewReader(payload))
++ req.Header.Set("Content-Type", "application/json")
++
++ err := ctx.AuthZRequest(httptest.NewRecorder(), req)
++ if err == nil {
++ t.Fatal("expected AuthZRequest to reject body over max size")
++ }
++ if !strings.Contains(err.Error(), "request body too large for authorization plugin") {
++ t.Fatalf("unexpected error: %v", err)
++ }
++
++ remaining, readErr := io.ReadAll(req.Body)
++ if readErr != nil {
++ t.Fatalf("failed to read request body after authz error: %v", readErr)
++ }
++ if string(remaining) != payload {
++ t.Fatalf("request body should still be preserved after over-limit check")
+ }
+ }
+
+--
+2.44.4
+
diff --git a/recipes-containers/docker/files/CVE-2026-34040_p2.patch b/recipes-containers/docker/files/CVE-2026-34040_p2.patch
new file mode 100644
index 00000000..00a264f0
--- /dev/null
+++ b/recipes-containers/docker/files/CVE-2026-34040_p2.patch
@@ -0,0 +1,39 @@
+From f24fa983ccaa393b64724292a49270ab46b49c06 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
+Date: Mon, 16 Feb 2026 14:16:06 +0100
+Subject: [PATCH 2/2] pkg/authz: Increase body limit to 4 MiB
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some endpoint could potentially use a body request than 1 MiB without
+malicious intent.
+
+CVE: CVE-2026-34040
+Upstream-Status: Backport [https://github.com/moby/moby/commit/4d0135c2d25b89ecc62a15277f2017715019569]
+
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit ec76e941838797fc762185c556c152f0a032d387)
+Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
+(cherry picked from commit 4d0135c2d25b89ecc62a15277f20177150195695)
+Signed-off-by: Deepak Rathore <deeratho@cisco.com>
+---
+ pkg/authorization/authz.go | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/pkg/authorization/authz.go b/pkg/authorization/authz.go
+index 3bc30f61cf..e9221307a7 100644
+--- a/pkg/authorization/authz.go
++++ b/pkg/authorization/authz.go
+@@ -16,7 +16,7 @@ import (
+ "github.com/docker/docker/pkg/ioutils"
+ )
+
+-const maxBodySize = 1048576 // 1MB
++const maxBodySize = 4 * 1024 * 1024 // 4MiB
+
+ // NewCtx creates new authZ context, it is used to store authorization information related to a specific docker
+ // REST http session
+--
+2.44.4
+
--
2.35.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [meta-virtualization][scarthgap][PATCH 2/2] docker-moby: Fix CVE-2026-34040
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
0 siblings, 0 replies; 3+ messages in thread
From: Bruce Ashfield @ 2026-05-28 3:03 UTC (permalink / raw)
To: deeratho; +Cc: meta-virtualization
merged.
Bruce
In message: [meta-virtualization][scarthgap][PATCH 2/2] docker-moby: Fix CVE-2026-34040
on 13/05/2026 Deepak Rathore via lists.yoctoproject.org wrote:
> From: Deepak Rathore <deeratho@cisco.com>
>
> The upstream fix [3] & [4] referenced in the Debian security
> advisory [5] is present in the v25.0 branch, which aligns with the
> scarthgap branch so pick the corresponding commit [1] & [2] to apply
> the CVE fix.
>
> [1] https://github.com/moby/moby/commit/553e8214614ee0d65ee309f148a8e865634cc291
> [2] https://github.com/moby/moby/commit/4d0135c2d25b89ecc62a15277f20177150195695
> [3] https://github.com/moby/moby/commit/6d311e0d8d4174a6347942db78c553fb7dc3762e
> [4] https://github.com/moby/moby/commit/db7dadaca041953430d1e2144088c311b78b96d7
> [5] https://security-tracker.debian.org/tracker/CVE-2026-34040
>
> 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 26dce276..eb493a43 100644
> --- a/recipes-containers/docker/docker-moby_git.bb
> +++ b/recipes-containers/docker/docker-moby_git.bb
> @@ -57,6 +57,8 @@ SRC_URI = "\
> 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 \
> + file://CVE-2026-34040_p1.patch;patchdir=src/import \
> + file://CVE-2026-34040_p2.patch;patchdir=src/import \
> "
>
> DOCKER_COMMIT = "${SRCREV_moby}"
> diff --git a/recipes-containers/docker/files/CVE-2026-34040_p1.patch b/recipes-containers/docker/files/CVE-2026-34040_p1.patch
> new file mode 100644
> index 00000000..9fb96ab0
> --- /dev/null
> +++ b/recipes-containers/docker/files/CVE-2026-34040_p1.patch
> @@ -0,0 +1,215 @@
> +From b2ff8a60155731641418d1a8b9efaf9e044e1971 Mon Sep 17 00:00:00 2001
> +From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
> +Date: Mon, 16 Feb 2026 14:15:24 +0100
> +Subject: [PATCH 1/2] pkg/authz: Reject requests exceeding body size limit
> +MIME-Version: 1.0
> +Content-Type: text/plain; charset=UTF-8
> +Content-Transfer-Encoding: 8bit
> +
> +Previously, the authorization system would silently skip body inspection when
> +request bodies exceeded the maximum size limit (1MiB).
> +
> +The authorization plugins would receive an empty body for inspection
> +while the actual large payload would still be processed by the Docker
> +daemon, allowing malicious requests to circumvent plugin-based security
> +controls.
> +
> +CVE: CVE-2026-34040
> +Upstream-Status: Backport [https://github.com/moby/moby/commit/553e8214614ee0d65ee309f148a8e865634cc291]
> +
> +Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
> +(cherry picked from commit 7a767b27fd1238c89a5cc926c39e27d3bcf58e35)
> +Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
> +(cherry picked from commit 553e8214614ee0d65ee309f148a8e865634cc291)
> +Signed-off-by: Deepak Rathore <deeratho@cisco.com>
> +---
> + pkg/authorization/authz.go | 56 ++++++-----------
> + pkg/authorization/authz_unix_test.go | 93 +++++++++++++++++++---------
> + 2 files changed, 83 insertions(+), 66 deletions(-)
> +
> +diff --git a/pkg/authorization/authz.go b/pkg/authorization/authz.go
> +index d568a2b597..3bc30f61cf 100644
> +--- a/pkg/authorization/authz.go
> ++++ b/pkg/authorization/authz.go
> +@@ -55,28 +55,31 @@ type Ctx struct {
> + authReq *Request
> + }
> +
> +-func isChunked(r *http.Request) bool {
> +- // RFC 7230 specifies that content length is to be ignored if Transfer-Encoding is chunked
> +- if strings.EqualFold(r.Header.Get("Transfer-Encoding"), "chunked") {
> +- return true
> +- }
> +- for _, v := range r.TransferEncoding {
> +- if strings.EqualFold(v, "chunked") {
> +- return true
> +- }
> +- }
> +- return false
> +-}
> +-
> + // AuthZRequest authorized the request to the docker daemon using authZ plugins
> + func (ctx *Ctx) AuthZRequest(w http.ResponseWriter, r *http.Request) error {
> + var body []byte
> +- if sendBody(ctx.requestURI, r.Header) && (r.ContentLength > 0 || isChunked(r)) && r.ContentLength < maxBodySize {
> +- var err error
> +- body, r.Body, err = drainBody(r.Body)
> +- if err != nil {
> ++ if sendBody(ctx.requestURI, r.Header) {
> ++ // Wrap the original request body in a buffered reader so we can inspect
> ++ // the prefix without consuming bytes from the downstream reader.
> ++ // `Peek(maxBodySize + 1)` is used as a size check:
> ++ // - err == nil means at least maxBodySize+1 bytes are buffered/available,
> ++ // so the payload exceeds the plugin limit and is rejected.
> ++ // - otherwise, `peeked` contains the complete body bytes currently available
> ++ // (for short bodies this is the full payload), and reads from r.Body still
> ++ // stream the original body unchanged.
> ++ bufBody := bufio.NewReaderSize(r.Body, maxBodySize+1)
> ++ r.Body = ioutils.NewReadCloserWrapper(bufBody, r.Body.Close)
> ++
> ++ peeked, err := bufBody.Peek(maxBodySize + 1)
> ++ if err == nil {
> ++ // Successfully peeked maxBodySize+1 bytes, so body is too large
> ++ // TODO: Allows plugin to opt in
> ++ return fmt.Errorf("request body too large for authorization plugin: size exceeds %d bytes", maxBodySize)
> ++ } else if err != io.EOF {
> + return err
> + }
> ++
> ++ body = peeked
> + }
> +
> + var h bytes.Buffer
> +@@ -142,25 +145,6 @@ func (ctx *Ctx) AuthZResponse(rm ResponseModifier, r *http.Request) error {
> + return nil
> + }
> +
> +-// drainBody dump the body (if its length is less than 1MB) without modifying the request state
> +-func drainBody(body io.ReadCloser) ([]byte, io.ReadCloser, error) {
> +- bufReader := bufio.NewReaderSize(body, maxBodySize)
> +- newBody := ioutils.NewReadCloserWrapper(bufReader, func() error { return body.Close() })
> +-
> +- data, err := bufReader.Peek(maxBodySize)
> +- // Body size exceeds max body size
> +- if err == nil {
> +- log.G(context.TODO()).Warnf("Request body is larger than: '%d' skipping body", maxBodySize)
> +- return nil, newBody, nil
> +- }
> +- // Body size is less than maximum size
> +- if err == io.EOF {
> +- return data, newBody, nil
> +- }
> +- // Unknown error
> +- return nil, newBody, err
> +-}
> +-
> + func isAuthEndpoint(urlPath string) (bool, error) {
> + // eg www.test.com/v1.24/auth/optional?optional1=something&optional2=something (version optional)
> + matched, err := regexp.MatchString(`^[^\/]*\/(v\d[\d\.]*\/)?auth.*`, urlPath)
> +diff --git a/pkg/authorization/authz_unix_test.go b/pkg/authorization/authz_unix_test.go
> +index 66b4d20452..c726e5f79a 100644
> +--- a/pkg/authorization/authz_unix_test.go
> ++++ b/pkg/authorization/authz_unix_test.go
> +@@ -139,36 +139,69 @@ func TestResponseModifier(t *testing.T) {
> + }
> + }
> +
> +-func TestDrainBody(t *testing.T) {
> +- tests := []struct {
> +- length int // length is the message length send to drainBody
> +- expectedBodyLength int // expectedBodyLength is the expected body length after drainBody is called
> +- }{
> +- {10, 10}, // Small message size
> +- {maxBodySize - 1, maxBodySize - 1}, // Max message size
> +- {maxBodySize * 2, 0}, // Large message size (skip copying body)
> +-
> +- }
> +-
> +- for _, test := range tests {
> +- msg := strings.Repeat("a", test.length)
> +- body, closer, err := drainBody(io.NopCloser(bytes.NewReader([]byte(msg))))
> +- if err != nil {
> +- t.Fatal(err)
> +- }
> +- if len(body) != test.expectedBodyLength {
> +- t.Fatalf("Body must be copied, actual length: '%d'", len(body))
> +- }
> +- if closer == nil {
> +- t.Fatal("Closer must not be nil")
> +- }
> +- modified, err := io.ReadAll(closer)
> +- if err != nil {
> +- t.Fatalf("Error must not be nil: '%v'", err)
> +- }
> +- if len(modified) != len(msg) {
> +- t.Fatalf("Result should not be truncated. Original length: '%d', new length: '%d'", len(msg), len(modified))
> +- }
> ++type recordingPlugin struct {
> ++ recordedRequest Request
> ++}
> ++
> ++func (p *recordingPlugin) Name() string { return "recording-plugin" }
> ++
> ++func (p *recordingPlugin) AuthZRequest(authReq *Request) (*Response, error) {
> ++ p.recordedRequest = *authReq
> ++ p.recordedRequest.RequestBody = bytes.Clone(authReq.RequestBody)
> ++ return &Response{Allow: true}, nil
> ++}
> ++
> ++func (p *recordingPlugin) AuthZResponse(_ *Request) (*Response, error) {
> ++ return &Response{Allow: true}, nil
> ++}
> ++
> ++func TestAuthZRequestBodyWithinLimit(t *testing.T) {
> ++ payload := strings.Repeat("a", maxBodySize)
> ++ plugin := &recordingPlugin{}
> ++ ctx := NewCtx([]Plugin{plugin}, "user", "tls", http.MethodPost, "/containers/create")
> ++
> ++ req := httptest.NewRequest(http.MethodPost, "http://example.com/containers/create", strings.NewReader(payload))
> ++ req.Header.Set("Content-Type", "application/json")
> ++
> ++ if err := ctx.AuthZRequest(httptest.NewRecorder(), req); err != nil {
> ++ t.Fatalf("AuthZRequest failed: %v", err)
> ++ }
> ++
> ++ if string(plugin.recordedRequest.RequestBody) != payload {
> ++ t.Fatalf("expected full request body to be sent to plugin, got length %d, expected %d", len(plugin.recordedRequest.RequestBody), len(payload))
> ++ }
> ++
> ++ remaining, err := io.ReadAll(req.Body)
> ++ if err != nil {
> ++ t.Fatalf("failed to read request body after authz: %v", err)
> ++ }
> ++ if string(remaining) != payload {
> ++ t.Fatalf("request body should be preserved for downstream readers")
> ++ }
> ++}
> ++
> ++func TestAuthZRequestBodyOverLimit(t *testing.T) {
> ++ payload := strings.Repeat("a", maxBodySize+1)
> ++ plugin := &recordingPlugin{}
> ++ ctx := NewCtx([]Plugin{plugin}, "user", "tls", http.MethodPost, "/containers/create")
> ++
> ++ req := httptest.NewRequest(http.MethodPost, "http://example.com/containers/create", strings.NewReader(payload))
> ++ req.Header.Set("Content-Type", "application/json")
> ++
> ++ err := ctx.AuthZRequest(httptest.NewRecorder(), req)
> ++ if err == nil {
> ++ t.Fatal("expected AuthZRequest to reject body over max size")
> ++ }
> ++ if !strings.Contains(err.Error(), "request body too large for authorization plugin") {
> ++ t.Fatalf("unexpected error: %v", err)
> ++ }
> ++
> ++ remaining, readErr := io.ReadAll(req.Body)
> ++ if readErr != nil {
> ++ t.Fatalf("failed to read request body after authz error: %v", readErr)
> ++ }
> ++ if string(remaining) != payload {
> ++ t.Fatalf("request body should still be preserved after over-limit check")
> + }
> + }
> +
> +--
> +2.44.4
> +
> diff --git a/recipes-containers/docker/files/CVE-2026-34040_p2.patch b/recipes-containers/docker/files/CVE-2026-34040_p2.patch
> new file mode 100644
> index 00000000..00a264f0
> --- /dev/null
> +++ b/recipes-containers/docker/files/CVE-2026-34040_p2.patch
> @@ -0,0 +1,39 @@
> +From f24fa983ccaa393b64724292a49270ab46b49c06 Mon Sep 17 00:00:00 2001
> +From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
> +Date: Mon, 16 Feb 2026 14:16:06 +0100
> +Subject: [PATCH 2/2] pkg/authz: Increase body limit to 4 MiB
> +MIME-Version: 1.0
> +Content-Type: text/plain; charset=UTF-8
> +Content-Transfer-Encoding: 8bit
> +
> +Some endpoint could potentially use a body request than 1 MiB without
> +malicious intent.
> +
> +CVE: CVE-2026-34040
> +Upstream-Status: Backport [https://github.com/moby/moby/commit/4d0135c2d25b89ecc62a15277f2017715019569]
> +
> +Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
> +(cherry picked from commit ec76e941838797fc762185c556c152f0a032d387)
> +Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
> +(cherry picked from commit 4d0135c2d25b89ecc62a15277f20177150195695)
> +Signed-off-by: Deepak Rathore <deeratho@cisco.com>
> +---
> + pkg/authorization/authz.go | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/pkg/authorization/authz.go b/pkg/authorization/authz.go
> +index 3bc30f61cf..e9221307a7 100644
> +--- a/pkg/authorization/authz.go
> ++++ b/pkg/authorization/authz.go
> +@@ -16,7 +16,7 @@ import (
> + "github.com/docker/docker/pkg/ioutils"
> + )
> +
> +-const maxBodySize = 1048576 // 1MB
> ++const maxBodySize = 4 * 1024 * 1024 // 4MiB
> +
> + // NewCtx creates new authZ context, it is used to store authorization information related to a specific docker
> + // REST http session
> +--
> +2.44.4
> +
> --
> 2.35.6
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#9795): https://lists.yoctoproject.org/g/meta-virtualization/message/9795
> Mute This Topic: https://lists.yoctoproject.org/mt/119298582/1050810
> Group Owner: meta-virtualization+owner@lists.yoctoproject.org
> Unsubscribe: https://lists.yoctoproject.org/g/meta-virtualization/unsub [bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
In message: [meta-virtualization][scarthgap][PATCH 1/2] docker-moby: Fix CVE-2026-33997
on 13/05/2026 Deepak Rathore via lists.yoctoproject.org wrote:
> 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
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#9794): https://lists.yoctoproject.org/g/meta-virtualization/message/9794
> Mute This Topic: https://lists.yoctoproject.org/mt/119298567/1050810
> Group Owner: meta-virtualization+owner@lists.yoctoproject.org
> Unsubscribe: https://lists.yoctoproject.org/g/meta-virtualization/unsub [bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
^ permalink raw reply [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.