Merge pull request #1049 from tonistiigi/llb-validation

llbsolver: add more llb validation
docker-19.03
Tibor Vass 2019-07-02 10:13:25 -07:00 committed by GitHub
commit fe8289063b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/moby/buildkit/frontend"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/solver/llbsolver"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/worker"
digest "github.com/opencontainers/go-digest"
@ -25,6 +26,9 @@ type buildOp struct {
}
func NewBuildOp(v solver.Vertex, op *pb.Op_Build, b frontend.FrontendLLBBridge, _ worker.Worker) (solver.Op, error) {
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
return nil, err
}
return &buildOp{
op: op.Build,
b: b,

View File

@ -60,6 +60,9 @@ type execOp struct {
}
func NewExecOp(v solver.Vertex, op *pb.Op_Exec, platform *pb.Platform, cm cache.Manager, sm *session.Manager, md *metadata.Store, exec executor.Executor, w worker.Worker) (solver.Op, error) {
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
return nil, err
}
return &execOp{
op: op.Exec,
cm: cm,

View File

@ -35,6 +35,9 @@ type fileOp struct {
}
func NewFileOp(v solver.Vertex, op *pb.Op_File, cm cache.Manager, md *metadata.Store, w worker.Worker) (solver.Op, error) {
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
return nil, err
}
return &fileOp{
op: op.File,
md: md,

View File

@ -7,6 +7,7 @@ import (
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/solver/llbsolver"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/source"
"github.com/moby/buildkit/worker"
@ -26,6 +27,9 @@ type sourceOp struct {
}
func NewSourceOp(_ solver.Vertex, op *pb.Op_Source, platform *pb.Platform, sm *source.Manager, sessM *session.Manager, w worker.Worker) (solver.Op, error) {
if err := llbsolver.ValidateOp(&pb.Op{Op: op}); err != nil {
return nil, err
}
return &sourceOp{
op: op,
sm: sm,

View File

@ -188,8 +188,15 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige
allOps[dgst] = &op
}
if len(allOps) < 2 {
return solver.Edge{}, errors.Errorf("invalid LLB with %d vertexes", len(allOps))
}
lastOp := allOps[dgst]
delete(allOps, dgst)
if len(lastOp.Inputs) == 0 {
return solver.Edge{}, errors.Errorf("invalid LLB with no inputs on last vertex")
}
dgst = lastOp.Inputs[0].Digest
cache := make(map[digest.Digest]solver.Vertex)
@ -203,6 +210,11 @@ func loadLLB(def *pb.Definition, fn func(digest.Digest, *pb.Op, func(digest.Dige
if !ok {
return nil, errors.Errorf("invalid missing input digest %s", dgst)
}
if err := ValidateOp(op); err != nil {
return nil, err
}
v, err := fn(dgst, op, rec)
if err != nil {
return nil, err
@ -240,6 +252,55 @@ func llbOpName(op *pb.Op) string {
}
}
func ValidateOp(op *pb.Op) error {
if op == nil {
return errors.Errorf("invalid nil op")
}
switch op := op.Op.(type) {
case *pb.Op_Source:
if op.Source == nil {
return errors.Errorf("invalid nil source op")
}
case *pb.Op_Exec:
if op.Exec == nil {
return errors.Errorf("invalid nil exec op")
}
if op.Exec.Meta == nil {
return errors.Errorf("invalid exec op with no meta")
}
if len(op.Exec.Meta.Args) == 0 {
return errors.Errorf("invalid exec op with no args")
}
if len(op.Exec.Mounts) == 0 {
return errors.Errorf("invalid exec op with no mounts")
}
isRoot := false
for _, m := range op.Exec.Mounts {
if m.Dest == pb.RootMount {
isRoot = true
break
}
}
if !isRoot {
return errors.Errorf("invalid exec op with no rootfs")
}
case *pb.Op_File:
if op.File == nil {
return errors.Errorf("invalid nil file op")
}
if len(op.File.Actions) == 0 {
return errors.Errorf("invalid file op with no actions")
}
case *pb.Op_Build:
if op.Build == nil {
return errors.Errorf("invalid nil build op")
}
}
return nil
}
func fileOpName(actions []*pb.FileAction) string {
names := make([]string, 0, len(actions))
for _, action := range actions {