Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 76edee9

Browse files
committed
fix(WORKDIR): use the config.User for the new dir permissions
WORKDIR ignores the currently set USER and creates the new directories with the root user ownership. This changes that, by executing a chown after the mkdir if needed, and also handle the case where the provided USER is an uid and the passwd file is not available to resolve to the username. Fixes #2259 Signed-off-by: Aris Buzachis <buzachis.aris@gmail.com>
1 parent f9aaa9f commit 76edee9

5 files changed

Lines changed: 66 additions & 12 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
FROM debian:9.11
2+
RUN groupadd -g 10000 bar
3+
RUN useradd -c "Foo user" -u 10000 -g 10000 -m foo
4+
5+
6+
# no passwd file
7+
FROM scratch
8+
9+
# without a USER Set
10+
WORKDIR /workdir/wo/user
11+
12+
USER 9999
13+
WORKDIR /workdir/w/uid
14+
15+
USER 9999:9999
16+
WORKDIR /workdir/w/uid_gid
17+
18+
USER 0
19+
WORKDIR /workdir/w/root_uid
20+
21+
USER root
22+
WORKDIR /workdir/w/root_username
23+
24+
# with passwd file
25+
COPY --from=0 /etc/passwd /etc/passwd
26+
COPY --from=0 /etc/group /etc/group
27+
28+
USER foo
29+
WORKDIR /workdir/w/foo_username
30+
31+
USER foo:10000
32+
WORKDIR /workdir/w/foo_username_gid
33+
34+
USER 10000
35+
WORKDIR /workdir/w/foo_uid
36+
37+
USER 10000:10000
38+
WORKDIR /workdir/w/foo_uid_gid
39+
40+
USER 10000:bar
41+
WORKDIR /workdir/w/foo_uid_groupname

pkg/commands/workdir.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"path/filepath"
2222

2323
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
24+
"github.com/pkg/errors"
2425

2526
"github.com/GoogleContainerTools/kaniko/pkg/util"
2627
v1 "github.com/google/go-containerregistry/pkg/v1"
@@ -35,7 +36,7 @@ type WorkdirCommand struct {
3536
}
3637

3738
// For testing
38-
var mkdir = os.MkdirAll
39+
var mkdirAllWithPermissions = util.MkdirAllWithPermissions
3940

4041
func (w *WorkdirCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
4142
logrus.Info("Cmd: workdir")
@@ -59,9 +60,21 @@ func (w *WorkdirCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile
5960
// Only create and snapshot the dir if it didn't exist already
6061
w.snapshotFiles = []string{}
6162
if _, err := os.Stat(config.WorkingDir); os.IsNotExist(err) {
62-
logrus.Infof("Creating directory %s", config.WorkingDir)
63+
uid, gid := int64(-1), int64(-1)
64+
65+
if config.User != "" {
66+
logrus.Debugf("Fetching uid and gid for USER '%s'", config.User)
67+
uid, gid, err = util.GetUserGroup(config.User, replacementEnvs)
68+
if err != nil {
69+
return errors.Wrapf(err, "identifying uid and gid for user %s", config.User)
70+
}
71+
}
72+
73+
logrus.Infof("Creating directory %s with uid %d and gid %d", config.WorkingDir, uid, gid)
6374
w.snapshotFiles = append(w.snapshotFiles, config.WorkingDir)
64-
return mkdir(config.WorkingDir, 0755)
75+
if err := mkdirAllWithPermissions(config.WorkingDir, 0755, uid, gid); err != nil {
76+
return errors.Wrapf(err, "creating workdir %s", config.WorkingDir)
77+
}
6578
}
6679
return nil
6780
}

pkg/commands/workdir_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,17 @@ var workdirTests = []struct {
8383
}
8484

8585
// For testing
86-
func mockDir(p string, fi os.FileMode) error {
86+
func mockDir(path string, mode os.FileMode, uid, gid int64) error {
8787
return nil
8888
}
8989
func TestWorkdirCommand(t *testing.T) {
9090

9191
// Mock out mkdir for testing.
92-
oldMkdir := mkdir
93-
mkdir = mockDir
92+
oldMkdir := mkdirAllWithPermissions
93+
mkdirAllWithPermissions = mockDir
9494

9595
defer func() {
96-
mkdir = oldMkdir
96+
mkdirAllWithPermissions = oldMkdir
9797
}()
9898

9999
cfg := &v1.Config{

pkg/util/command_util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,8 @@ func LookupUser(userStr string) (*user.User, error) {
442442
userObj, err := user.Lookup(userStr)
443443
if err != nil {
444444
unknownUserErr := new(user.UnknownUserError)
445-
// only return if it's not an unknown user error
446-
if !errors.As(err, unknownUserErr) {
445+
// only return if it's not an unknown user error or the passwd does not exist
446+
if !errors.As(err, unknownUserErr) && !strings.Contains(err.Error(), "no such file") {
447447
return nil, err
448448
}
449449

pkg/util/fs_util.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ func ExtractFile(dest string, hdr *tar.Header, tr io.Reader) error {
348348
currFile.Close()
349349
case tar.TypeDir:
350350
logrus.Tracef("Creating dir %s", path)
351-
if err := mkdirAllWithPermissions(path, mode, int64(uid), int64(gid)); err != nil {
351+
if err := MkdirAllWithPermissions(path, mode, int64(uid), int64(gid)); err != nil {
352352
return err
353353
}
354354

@@ -663,7 +663,7 @@ func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, e
663663

664664
mode := fi.Mode()
665665
uid, gid := DetermineTargetFileOwnership(fi, uid, gid)
666-
if err := mkdirAllWithPermissions(destPath, mode, uid, gid); err != nil {
666+
if err := MkdirAllWithPermissions(destPath, mode, uid, gid); err != nil {
667667
return nil, err
668668
}
669669
} else if IsSymlink(fi) {
@@ -806,7 +806,7 @@ func Volumes() []string {
806806
return volumes
807807
}
808808

809-
func mkdirAllWithPermissions(path string, mode os.FileMode, uid, gid int64) error {
809+
func MkdirAllWithPermissions(path string, mode os.FileMode, uid, gid int64) error {
810810
// Check if a file already exists on the path, if yes then delete it
811811
info, err := os.Stat(path)
812812
if err == nil && !info.IsDir() {

0 commit comments

Comments
 (0)