Skip to content

Commit

Permalink
Merge pull request #2867 from crazy-max/v0.19_backport_entitlement-pa…
Browse files Browse the repository at this point in the history
…th-fix

[v0.19 backport] bake: change evaluation of entitlement paths
  • Loading branch information
crazy-max authored Dec 17, 2024
2 parents 62d486d + 2bd4aef commit 48d6a39
Show file tree
Hide file tree
Showing 3 changed files with 328 additions and 13 deletions.
31 changes: 20 additions & 11 deletions bake/entitlements.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/docker/buildx/util/osutil"
"github.com/moby/buildkit/util/entitlements"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

type EntitlementKey string
Expand Down Expand Up @@ -443,13 +444,21 @@ func evaluatePaths(in []string) ([]string, bool, error) {
continue
}
v, err := filepath.Abs(p)
if err != nil {
logrus.Warnf("failed to evaluate entitlement path %q: %v", p, err)
continue
}
v, rest, err := evaluateToExistingPath(v)
if err != nil {
return nil, false, errors.Wrapf(err, "failed to evaluate path %q", p)
}
v, err = filepath.EvalSymlinks(v)
v, err = osutil.GetLongPathName(v)
if err != nil {
return nil, false, errors.Wrapf(err, "failed to evaluate path %q", p)
}
if rest != "" {
v = filepath.Join(v, rest)
}
out = append(out, v)
}
return out, allowAny, nil
Expand All @@ -458,7 +467,7 @@ func evaluatePaths(in []string) ([]string, bool, error) {
func evaluateToExistingPaths(in map[string]struct{}) (map[string]struct{}, error) {
m := make(map[string]struct{}, len(in))
for p := range in {
v, err := evaluateToExistingPath(p)
v, _, err := evaluateToExistingPath(p)
if err != nil {
return nil, errors.Wrapf(err, "failed to evaluate path %q", p)
}
Expand All @@ -471,10 +480,10 @@ func evaluateToExistingPaths(in map[string]struct{}) (map[string]struct{}, error
return m, nil
}

func evaluateToExistingPath(in string) (string, error) {
func evaluateToExistingPath(in string) (string, string, error) {
in, err := filepath.Abs(in)
if err != nil {
return "", err
return "", "", err
}

volLen := volumeNameLen(in)
Expand Down Expand Up @@ -529,29 +538,29 @@ func evaluateToExistingPath(in string) (string, error) {
if os.IsNotExist(err) {
for r := len(dest) - 1; r >= volLen; r-- {
if os.IsPathSeparator(dest[r]) {
return dest[:r], nil
return dest[:r], in[start:], nil
}
}
return vol, nil
return vol, in[start:], nil
}
return "", err
return "", "", err
}

if fi.Mode()&fs.ModeSymlink == 0 {
if !fi.Mode().IsDir() && end < len(in) {
return "", syscall.ENOTDIR
return "", "", syscall.ENOTDIR
}
continue
}

linksWalked++
if linksWalked > 255 {
return "", errors.New("too many symlinks")
return "", "", errors.New("too many symlinks")
}

link, err := os.Readlink(dest)
if err != nil {
return "", err
return "", "", err
}

in = link + in[end:]
Expand Down Expand Up @@ -584,7 +593,7 @@ func evaluateToExistingPath(in string) (string, error) {
end = 0
}
}
return filepath.Clean(dest), nil
return filepath.Clean(dest), "", nil
}

func volumeNameLen(s string) int {
Expand Down
46 changes: 44 additions & 2 deletions bake/entitlements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestEvaluateToExistingPath(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := evaluateToExistingPath(tt.input)
result, _, err := evaluateToExistingPath(tt.input)

if tt.expectErr {
require.Error(t, err)
Expand Down Expand Up @@ -341,7 +341,7 @@ func TestValidateEntitlements(t *testing.T) {
return nil
}
// if not, then escapeLink is not allowed
exp, err := evaluateToExistingPath(escapeLink)
exp, _, err := evaluateToExistingPath(escapeLink)
require.NoError(t, err)
exp, err = filepath.EvalSymlinks(exp)
require.NoError(t, err)
Expand All @@ -363,6 +363,48 @@ func TestValidateEntitlements(t *testing.T) {
},
expected: EntitlementConf{},
},
{
name: "NonExistingAllowedPathSubpath",
opt: build.Options{
ExportsLocalPathsTemporary: []string{
dir1,
},
},
conf: EntitlementConf{
FSRead: []string{wd},
FSWrite: []string{filepath.Join(dir1, "not/exists")},
},
expected: EntitlementConf{
FSWrite: []string{expDir1}, // dir1 is still needed as only subpath was allowed
},
},
{
name: "NonExistingAllowedPathMatches",
opt: build.Options{
ExportsLocalPathsTemporary: []string{
filepath.Join(dir1, "not/exists"),
},
},
conf: EntitlementConf{
FSRead: []string{wd},
FSWrite: []string{filepath.Join(dir1, "not/exists")},
},
expected: EntitlementConf{
FSWrite: []string{expDir1}, // dir1 is still needed as build also needs to write not/exists directory
},
},
{
name: "NonExistingBuildPath",
opt: build.Options{
ExportsLocalPathsTemporary: []string{
filepath.Join(dir1, "not/exists"),
},
},
conf: EntitlementConf{
FSRead: []string{wd},
FSWrite: []string{dir1},
},
},
}

for _, tc := range tcases {
Expand Down
Loading

0 comments on commit 48d6a39

Please sign in to comment.