瀏覽代碼

Merge pull request #41842 from jchorl/master

Reject null manifests during tar import
Sebastiaan van Stijn 4 年之前
父節點
當前提交
1c39b1c44c
共有 3 個文件被更改,包括 52 次插入1 次删除
  1. 1 1
      daemon/images/image_exporter.go
  2. 14 0
      image/tarexport/load.go
  3. 37 0
      image/tarexport/load_test.go

+ 1 - 1
daemon/images/image_exporter.go

@@ -17,7 +17,7 @@ func (i *ImageService) ExportImage(names []string, outStream io.Writer) error {
 }
 
 // LoadImage uploads a set of images into the repository. This is the
-// complement of ImageExport.  The input stream is an uncompressed tar
+// complement of ExportImage.  The input stream is an uncompressed tar
 // ball containing images and metadata.
 func (i *ImageService) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
 	imageExporter := tarexport.NewTarExporter(i.imageStore, i.layerStores, i.referenceStore, i)

+ 14 - 0
image/tarexport/load.go

@@ -63,6 +63,10 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
 		return err
 	}
 
+	if err := validateManifest(manifest); err != nil {
+		return err
+	}
+
 	var parentLinks []parentLink
 	var imageIDsStr string
 	var imageRefCount int
@@ -430,3 +434,13 @@ func checkCompatibleOS(imageOS string) error {
 
 	return system.ValidatePlatform(p)
 }
+
+func validateManifest(manifest []manifestItem) error {
+	// a nil manifest usually indicates a bug, so don't just silently fail.
+	// if someone really needs to pass an empty manifest, they can pass [].
+	if manifest == nil {
+		return errors.New("invalid manifest, manifest cannot be null (but can be [])")
+	}
+
+	return nil
+}

+ 37 - 0
image/tarexport/load_test.go

@@ -0,0 +1,37 @@
+package tarexport
+
+import (
+	"testing"
+
+	"gotest.tools/v3/assert"
+	is "gotest.tools/v3/assert/cmp"
+)
+
+func TestValidateManifest(t *testing.T) {
+	cases := map[string]struct {
+		manifest    []manifestItem
+		valid       bool
+		errContains string
+	}{
+		"nil": {
+			manifest:    nil,
+			valid:       false,
+			errContains: "manifest cannot be null",
+		},
+		"non-nil": {
+			manifest: []manifestItem{},
+			valid:    true,
+		},
+	}
+
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			err := validateManifest(tc.manifest)
+			if tc.valid {
+				assert.Check(t, is.Nil(err))
+			} else {
+				assert.Check(t, is.ErrorContains(err, tc.errContains))
+			}
+		})
+	}
+}