Skip to content

Commit 18ccba0

Browse files
authored
Merge pull request #3068 from crazy-max/GHSA-m4gq-fm9h-8q75
cherry-picks for CVE-2025-0495
2 parents 00fdcd3 + f5196f1 commit 18ccba0

File tree

6 files changed

+105
-33
lines changed

6 files changed

+105
-33
lines changed

commands/bake.go

+17-15
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ type bakeOptions struct {
6666
func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in bakeOptions, cFlags commonFlags) (err error) {
6767
mp := dockerCli.MeterProvider()
6868

69-
ctx, end, err := tracing.TraceCurrentCommand(ctx, "bake")
69+
ctx, end, err := tracing.TraceCurrentCommand(ctx, append([]string{"bake"}, targets...),
70+
attribute.String("builder", in.builder),
71+
attribute.StringSlice("targets", targets),
72+
attribute.StringSlice("files", in.files),
73+
)
7074
if err != nil {
7175
return err
7276
}
@@ -283,7 +287,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
283287
}
284288
}
285289

286-
if err := saveLocalStateGroup(dockerCli, in, targets, bo, overrides, def); err != nil {
290+
if err := saveLocalStateGroup(dockerCli, in, targets, bo); err != nil {
287291
return err
288292
}
289293

@@ -488,7 +492,14 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
488492
return cmd
489493
}
490494

491-
func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options, overrides []string, def any) error {
495+
func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string, bo map[string]build.Options) error {
496+
l, err := localstate.New(confutil.NewConfig(dockerCli))
497+
if err != nil {
498+
return err
499+
}
500+
501+
defer l.MigrateIfNeeded()
502+
492503
prm := confutil.MetadataProvenance()
493504
if len(in.metadataFile) == 0 {
494505
prm = confutil.MetadataProvenanceModeDisabled
@@ -508,19 +519,10 @@ func saveLocalStateGroup(dockerCli command.Cli, in bakeOptions, targets []string
508519
if len(refs) == 0 {
509520
return nil
510521
}
511-
l, err := localstate.New(confutil.NewConfig(dockerCli))
512-
if err != nil {
513-
return err
514-
}
515-
dtdef, err := json.MarshalIndent(def, "", " ")
516-
if err != nil {
517-
return err
518-
}
522+
519523
return l.SaveGroup(groupRef, localstate.StateGroup{
520-
Definition: dtdef,
521-
Targets: targets,
522-
Inputs: overrides,
523-
Refs: refs,
524+
Refs: refs,
525+
Targets: targets,
524526
})
525527
}
526528

commands/build.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,11 @@ func (o *buildOptionsHash) String() string {
286286
func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) (err error) {
287287
mp := dockerCli.MeterProvider()
288288

289-
ctx, end, err := tracing.TraceCurrentCommand(ctx, "build")
289+
ctx, end, err := tracing.TraceCurrentCommand(ctx, []string{"build", options.contextPath},
290+
attribute.String("builder", options.builder),
291+
attribute.String("context", options.contextPath),
292+
attribute.String("dockerfile", options.dockerfileName),
293+
)
290294
if err != nil {
291295
return err
292296
}

localstate/localstate.go

+22-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"os"
88
"path/filepath"
9+
"strconv"
910
"sync"
1011

1112
"github.com/docker/buildx/util/confutil"
@@ -14,6 +15,7 @@ import (
1415
)
1516

1617
const (
18+
version = 2
1719
refsDir = "refs"
1820
groupDir = "__group__"
1921
)
@@ -31,12 +33,8 @@ type State struct {
3133
}
3234

3335
type StateGroup struct {
34-
// Definition is the raw representation of the group (bake definition)
35-
Definition []byte
3636
// Targets are the targets invoked
3737
Targets []string `json:",omitempty"`
38-
// Inputs are the user inputs (bake overrides)
39-
Inputs []string `json:",omitempty"`
4038
// Refs are used to track all the refs that belong to the same group
4139
Refs []string
4240
}
@@ -52,9 +50,7 @@ func New(cfg *confutil.Config) (*LocalState, error) {
5250
if err := cfg.MkdirAll(refsDir, 0700); err != nil {
5351
return nil, err
5452
}
55-
return &LocalState{
56-
cfg: cfg,
57-
}, nil
53+
return &LocalState{cfg: cfg}, nil
5854
}
5955

6056
func (ls *LocalState) ReadRef(builderName, nodeName, id string) (*State, error) {
@@ -87,8 +83,12 @@ func (ls *LocalState) SaveRef(builderName, nodeName, id string, st State) error
8783
return ls.cfg.AtomicWriteFile(filepath.Join(refDir, id), dt, 0644)
8884
}
8985

86+
func (ls *LocalState) GroupDir() string {
87+
return filepath.Join(ls.cfg.Dir(), refsDir, groupDir)
88+
}
89+
9090
func (ls *LocalState) ReadGroup(id string) (*StateGroup, error) {
91-
dt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id))
91+
dt, err := os.ReadFile(filepath.Join(ls.GroupDir(), id))
9292
if err != nil {
9393
return nil, err
9494
}
@@ -208,7 +208,7 @@ func (ls *LocalState) removeGroup(id string) error {
208208
if id == "" {
209209
return errors.Errorf("group ref empty")
210210
}
211-
f := filepath.Join(ls.cfg.Dir(), refsDir, groupDir, id)
211+
f := filepath.Join(ls.GroupDir(), id)
212212
if _, err := os.Lstat(f); err != nil {
213213
if !os.IsNotExist(err) {
214214
return err
@@ -230,3 +230,16 @@ func (ls *LocalState) validate(builderName, nodeName, id string) error {
230230
}
231231
return nil
232232
}
233+
234+
func (ls *LocalState) readVersion() int {
235+
if vdt, err := os.ReadFile(filepath.Join(ls.cfg.Dir(), refsDir, "version")); err == nil {
236+
if v, err := strconv.Atoi(string(vdt)); err == nil {
237+
return v
238+
}
239+
}
240+
return 1
241+
}
242+
243+
func (ls *LocalState) writeVersion(version int) error {
244+
return ls.cfg.AtomicWriteFile(filepath.Join(refsDir, "version"), []byte(strconv.Itoa(version)), 0600)
245+
}

localstate/localstate_test.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ var (
6868

6969
testStateGroupID = "kvqs0sgly2rmitz84r25u9qd0"
7070
testStateGroup = StateGroup{
71-
Definition: []byte(`{"group":{"default":{"targets":["pre-checkin"]},"pre-checkin":{"targets":["vendor-update","format","build"]}},"target":{"build":{"context":".","dockerfile":"dev.Dockerfile","target":"build-update","platforms":["linux/amd64"],"output":["."]},"format":{"context":".","dockerfile":"dev.Dockerfile","target":"format-update","platforms":["linux/amd64"],"output":["."]},"vendor-update":{"context":".","dockerfile":"dev.Dockerfile","target":"vendor-update","platforms":["linux/amd64"],"output":["."]}}}`),
72-
Targets: []string{"pre-checkin"},
73-
Inputs: []string{"*.platform=linux/amd64"},
74-
Refs: []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
71+
Targets: []string{"pre-checkin"},
72+
Refs: []string{"builder/builder0/hx2qf1w11qvz1x3k471c5i8xw", "builder/builder0/968zj0g03jmlx0s8qslnvh6rl", "builder/builder0/naf44f9i1710lf7y12lv5hb1z"},
7573
}
7674

7775
testStateGroupRef1ID = "hx2qf1w11qvz1x3k471c5i8xw"

localstate/migrate.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package localstate
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
8+
"github.com/pkg/errors"
9+
)
10+
11+
func (ls *LocalState) MigrateIfNeeded() error {
12+
currentVersion := ls.readVersion()
13+
if currentVersion == version {
14+
return nil
15+
}
16+
migrations := map[int]func(*LocalState) error{
17+
2: (*LocalState).migration2,
18+
}
19+
for v := currentVersion + 1; v <= version; v++ {
20+
migration, found := migrations[v]
21+
if !found {
22+
return errors.Errorf("localstate migration v%d not found", v)
23+
}
24+
if err := migration(ls); err != nil {
25+
return errors.Wrapf(err, "localstate migration v%d failed", v)
26+
}
27+
}
28+
return ls.writeVersion(version)
29+
}
30+
31+
func (ls *LocalState) migration2() error {
32+
return filepath.Walk(ls.GroupDir(), func(path string, info os.FileInfo, err error) error {
33+
if err != nil {
34+
return err
35+
}
36+
if info.IsDir() {
37+
return nil
38+
}
39+
dt, err := os.ReadFile(path)
40+
if err != nil {
41+
return err
42+
}
43+
var stg StateGroup
44+
if err := json.Unmarshal(dt, &stg); err != nil {
45+
return err
46+
}
47+
mdt, err := json.Marshal(stg)
48+
if err != nil {
49+
return err
50+
}
51+
if err := os.WriteFile(path, mdt, 0600); err != nil {
52+
return err
53+
}
54+
return nil
55+
})
56+
}

util/tracing/trace.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package tracing
22

33
import (
44
"context"
5-
"os"
65
"strings"
76

87
"github.com/moby/buildkit/util/tracing/delegated"
@@ -13,7 +12,7 @@ import (
1312
"go.opentelemetry.io/otel/trace"
1413
)
1514

16-
func TraceCurrentCommand(ctx context.Context, name string) (context.Context, func(error), error) {
15+
func TraceCurrentCommand(ctx context.Context, args []string, attrs ...attribute.KeyValue) (context.Context, func(error), error) {
1716
opts := []sdktrace.TracerProviderOption{
1817
sdktrace.WithResource(detect.Resource()),
1918
sdktrace.WithBatcher(delegated.DefaultExporter),
@@ -25,8 +24,8 @@ func TraceCurrentCommand(ctx context.Context, name string) (context.Context, fun
2524
}
2625

2726
tp := sdktrace.NewTracerProvider(opts...)
28-
ctx, span := tp.Tracer("").Start(ctx, name, trace.WithAttributes(
29-
attribute.String("command", strings.Join(os.Args, " ")),
27+
ctx, span := tp.Tracer("").Start(ctx, strings.Join(args, " "), trace.WithAttributes(
28+
attrs...,
3029
))
3130

3231
return ctx, func(err error) {

0 commit comments

Comments
 (0)