containerd/patch/0090-images-validate-document-type-before-unmarshal.patch
zhongjiawei d49c9d0693 containerd: bugfix and add CGO security build option
(cherry picked from commit eb136438cf63fae5754c31920a6bf8afaeded135)
2022-09-22 19:38:32 +08:00

118 lines
4.0 KiB
Diff

From e3e70b398ff362182797e2d73372f8f654ba9383 Mon Sep 17 00:00:00 2001
From: Vanient <xiadanni1@huawei.com>
Date: Thu, 9 Jun 2022 10:45:47 +0800
Subject: [PATCH 1/2] images: validate document type before unmarshal
Conflict:NA
Reference:https://github.com/containerd/containerd/commit/eb9ba7ed8d46d48fb22362f9d91fff6fb837e37e
Signed-off-by: Vanient <xiadanni1@huawei.com>
---
images/image.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/images/image.go b/images/image.go
index f72684d82..ad12fe971 100644
--- a/images/image.go
+++ b/images/image.go
@@ -19,6 +19,7 @@ package images
import (
"context"
"encoding/json"
+ "fmt"
"sort"
"strings"
"time"
@@ -154,6 +155,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var manifest ocispec.Manifest
if err := json.Unmarshal(p, &manifest); err != nil {
return nil, err
@@ -194,6 +199,10 @@ func Manifest(ctx context.Context, provider content.Provider, image ocispec.Desc
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "manifest: invalid desc %s", desc.Digest)
+ }
+
var idx ocispec.Index
if err := json.Unmarshal(p, &idx); err != nil {
return nil, err
@@ -335,6 +344,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
// TODO(stevvooe): We just assume oci manifest, for now. There may be
// subtle differences from the docker version.
var manifest ocispec.Manifest
@@ -350,6 +363,10 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return nil, err
}
+ if err := validateMediaType(p, desc.MediaType); err != nil {
+ return nil, errors.Wrapf(err, "children: invalid desc %s", desc.Digest)
+ }
+
var index ocispec.Index
if err := json.Unmarshal(p, &index); err != nil {
return nil, err
@@ -371,6 +388,44 @@ func Children(ctx context.Context, provider content.Provider, desc ocispec.Descr
return descs, nil
}
+// unknownDocument represents a manifest, manifest list, or index that has not
+// yet been validated.
+type unknownDocument struct {
+ MediaType string `json:"mediaType,omitempty"`
+ Config json.RawMessage `json:"config,omitempty"`
+ Layers json.RawMessage `json:"layers,omitempty"`
+ Manifests json.RawMessage `json:"manifests,omitempty"`
+ FSLayers json.RawMessage `json:"fsLayers,omitempty"` // schema 1
+}
+
+// validateMediaType returns an error if the byte slice is invalid JSON or if
+// the media type identifies the blob as one format but it contains elements of
+// another format.
+func validateMediaType(b []byte, mt string) error {
+ var doc unknownDocument
+ if err := json.Unmarshal(b, &doc); err != nil {
+ return err
+ }
+ if len(doc.FSLayers) != 0 {
+ return fmt.Errorf("media-type: schema 1 not supported")
+ }
+ switch mt {
+ case MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
+ if len(doc.Manifests) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2ManifestList ||
+ doc.MediaType == ocispec.MediaTypeImageIndex {
+ return fmt.Errorf("media-type: expected manifest but found index (%s)", mt)
+ }
+ case MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
+ if len(doc.Config) != 0 || len(doc.Layers) != 0 ||
+ doc.MediaType == MediaTypeDockerSchema2Manifest ||
+ doc.MediaType == ocispec.MediaTypeImageManifest {
+ return fmt.Errorf("media-type: expected index but found manifest (%s)", mt)
+ }
+ }
+ return nil
+}
+
// RootFS returns the unpacked diffids that make up and images rootfs.
//
// These are used to verify that a set of layers unpacked to the expected
--
2.27.0