From 6ec0d4a3ad495711fdeb61e675b9d1b3f6881c3a Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Tue, 29 Aug 2023 23:16:51 +0530 Subject: [PATCH 1/2] prevent ctr from creating tags with forbidden characters check if the target tag that is to be created using ctr image tag is valid and does not contain any forbidden characters. Signed-off-by: Akhil Mohan --- cmd/ctr/commands/images/tag.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/ctr/commands/images/tag.go b/cmd/ctr/commands/images/tag.go index 40b42926c..e145054e5 100644 --- a/cmd/ctr/commands/images/tag.go +++ b/cmd/ctr/commands/images/tag.go @@ -24,6 +24,7 @@ import ( "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/pkg/transfer/image" + "github.com/containerd/containerd/reference/docker" ) var tagCommand = cli.Command{ @@ -60,6 +61,9 @@ var tagCommand = cli.Command{ if !context.BoolT("local") { for _, targetRef := range context.Args()[1:] { + if _, err := docker.ParseAnyReference(targetRef); err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + } err = client.Transfer(ctx, image.NewStore(ref), image.NewStore(targetRef)) if err != nil { return err @@ -82,6 +86,9 @@ var tagCommand = cli.Command{ } // Support multiple references for one command run for _, targetRef := range context.Args()[1:] { + if _, err := docker.ParseAnyReference(targetRef); err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + } image.Name = targetRef // Attempt to create the image first if _, err = imageService.Create(ctx, image); err != nil { From 4b59d67dd40f20554eeb331107e5f06b21143cff Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Wed, 6 Sep 2023 17:01:45 +0530 Subject: [PATCH 2/2] add a new flag "skip-reference-check" to skip reference name check Signed-off-by: Akhil Mohan --- cmd/ctr/commands/images/tag.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cmd/ctr/commands/images/tag.go b/cmd/ctr/commands/images/tag.go index e145054e5..fbd1c5aa0 100644 --- a/cmd/ctr/commands/images/tag.go +++ b/cmd/ctr/commands/images/tag.go @@ -24,7 +24,7 @@ import ( "github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/pkg/transfer/image" - "github.com/containerd/containerd/reference/docker" + "github.com/distribution/reference" ) var tagCommand = cli.Command{ @@ -41,6 +41,10 @@ var tagCommand = cli.Command{ Name: "local", Usage: "Run tag locally rather than through transfer API", }, + cli.BoolFlag{ + Name: "skip-reference-check", + Usage: "Skip the strict check for reference names", + }, }, Action: func(context *cli.Context) error { var ( @@ -61,8 +65,10 @@ var tagCommand = cli.Command{ if !context.BoolT("local") { for _, targetRef := range context.Args()[1:] { - if _, err := docker.ParseAnyReference(targetRef); err != nil { - return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + if !context.Bool("skip-reference-check") { + if _, err := reference.ParseAnyReference(targetRef); err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + } } err = client.Transfer(ctx, image.NewStore(ref), image.NewStore(targetRef)) if err != nil { @@ -86,8 +92,10 @@ var tagCommand = cli.Command{ } // Support multiple references for one command run for _, targetRef := range context.Args()[1:] { - if _, err := docker.ParseAnyReference(targetRef); err != nil { - return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + if !context.Bool("skip-reference-check") { + if _, err := reference.ParseAnyReference(targetRef); err != nil { + return fmt.Errorf("error parsing reference: %q is not a valid repository/tag %v", targetRef, err) + } } image.Name = targetRef // Attempt to create the image first