From 654f854faecb038cb5ff110e6705fe355f1c8159 Mon Sep 17 00:00:00 2001 From: Josh Chorlton Date: Sat, 26 Dec 2020 00:55:24 +0000 Subject: [PATCH] reject null manifests Signed-off-by: Josh Chorlton --- daemon/images/image_exporter.go | 2 +- image/tarexport/load.go | 14 +++++++++++++ image/tarexport/load_test.go | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 image/tarexport/load_test.go diff --git a/daemon/images/image_exporter.go b/daemon/images/image_exporter.go index 58105dcb71..deb504020a 100644 --- a/daemon/images/image_exporter.go +++ b/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) diff --git a/image/tarexport/load.go b/image/tarexport/load.go index bbbb238b2b..090414d26e 100644 --- a/image/tarexport/load.go +++ b/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 +} diff --git a/image/tarexport/load_test.go b/image/tarexport/load_test.go new file mode 100644 index 0000000000..3121e1f2c0 --- /dev/null +++ b/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)) + } + }) + } +}