From 7c9e85c6d9e1036aa5469e74072c20c03fe0ffe9 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Tue, 6 Oct 2020 19:30:07 +0000 Subject: [PATCH] [PATCH] Ensure MkdirAllAndChown also sets perms Generally if we ever need to change perms of a dir, between versions, this ensures the permissions actually change when we think it should change without having to handle special cases if it already existed. Signed-off-by: Brian Goff (cherry picked from commit edb62a3ace8c4303822a391b38231e577f8c2ee8) Signed-off-by: Tibor Vass Gbp-Pq: Name cve-2021-21284-1.patch --- engine/pkg/idtools/idtools.go | 11 ++++++++--- engine/pkg/idtools/idtools_unix.go | 14 ++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/engine/pkg/idtools/idtools.go b/engine/pkg/idtools/idtools.go index 230422ea..3e2ce753 100644 --- a/engine/pkg/idtools/idtools.go +++ b/engine/pkg/idtools/idtools.go @@ -36,13 +36,13 @@ const ( // MkdirAllAndChown creates a directory (include any along the path) and then modifies // ownership to the requested uid/gid. If the directory already exists, this -// function will still change ownership to the requested uid/gid pair. +// function will still change ownership and permissions. func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error { return mkdirAs(path, mode, owner, true, true) } // MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid. -// If the directory already exists, this function still changes ownership. +// If the directory already exists, this function still changes ownership and permissions. // Note that unlike os.Mkdir(), this function does not return IsExist error // in case path already exists. func MkdirAndChown(path string, mode os.FileMode, owner Identity) error { @@ -51,7 +51,7 @@ func MkdirAndChown(path string, mode os.FileMode, owner Identity) error { // MkdirAllAndChownNew creates a directory (include any along the path) and then modifies // ownership ONLY of newly created directories to the requested uid/gid. If the -// directories along the path exist, no change of ownership will be performed +// directories along the path exist, no change of ownership or permissions will be performed func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error { return mkdirAs(path, mode, owner, true, false) } @@ -265,3 +265,8 @@ func parseSubidFile(path, username string) (ranges, error) { } return rangeList, nil } + +// CurrentIdentity returns the identity of the current process +func CurrentIdentity() Identity { + return Identity{UID: os.Getuid(), GID: os.Getegid()} +} diff --git a/engine/pkg/idtools/idtools_unix.go b/engine/pkg/idtools/idtools_unix.go index fb239743..329d5d04 100644 --- a/engine/pkg/idtools/idtools_unix.go +++ b/engine/pkg/idtools/idtools_unix.go @@ -39,7 +39,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting } // short-circuit--we were called with an existing directory and chown was requested - return lazyChown(path, owner.UID, owner.GID, stat) + return setPermissions(path, mode, owner.UID, owner.GID, stat) } if os.IsNotExist(err) { @@ -70,7 +70,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting // even if it existed, we will chown the requested path + any subpaths that // didn't exist when we called MkdirAll for _, pathComponent := range paths { - if err := lazyChown(pathComponent, owner.UID, owner.GID, nil); err != nil { + if err := setPermissions(pathComponent, mode, owner.UID, owner.GID, nil); err != nil { return err } } @@ -213,10 +213,11 @@ func callGetent(args string) (io.Reader, error) { return bytes.NewReader(out), nil } -// lazyChown performs a chown only if the uid/gid don't match what's requested +// setPermissions performs a chown/chmod only if the uid/gid don't match what's requested // Normally a Chown is a no-op if uid/gid match, but in some cases this can still cause an error, e.g. if the // dir is on an NFS share, so don't call chown unless we absolutely must. -func lazyChown(p string, uid, gid int, stat *system.StatT) error { +// Likewise for setting permissions. +func setPermissions(p string, mode os.FileMode, uid, gid int, stat *system.StatT) error { if stat == nil { var err error stat, err = system.Stat(p) @@ -224,6 +225,11 @@ func lazyChown(p string, uid, gid int, stat *system.StatT) error { return err } } + if os.FileMode(stat.Mode()).Perm() != mode.Perm() { + if err := os.Chmod(p, mode.Perm()); err != nil { + return err + } + } if stat.UID() == uint32(uid) && stat.GID() == uint32(gid) { return nil } -- 2.30.2