From ebafab47ca2ab98148a5149e554ae240128ad613 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 14 Aug 2017 16:01:40 +0100 Subject: [PATCH] correct container "/" ownership with userns Previously "`/`" in a container was always owned by `root:root` (0/0), even if `withRemappedSnapshot` had been used. Meaning that if `withUserNamespace` is used then `/` can be remapped to `nobody:nogroup` (65534/65534). The fix is is twofold: - incrementFS should operate on the root of the tree. - when creating a new snapshot we must propagate the ownership of the topmost "lower" directory into the new "upper". Signed-off-by: Ian Campbell --- snapshot/overlay/overlay.go | 23 ++++++++++++++++++++++- spec_unix.go | 3 --- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/snapshot/overlay/overlay.go b/snapshot/overlay/overlay.go index 35644b07a..d68233920 100644 --- a/snapshot/overlay/overlay.go +++ b/snapshot/overlay/overlay.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "strings" + "syscall" "github.com/containerd/containerd/fs" "github.com/containerd/containerd/log" @@ -274,7 +275,8 @@ func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshot.Kind, ke } }() - if err = os.MkdirAll(filepath.Join(td, "fs"), 0755); err != nil { + fs := filepath.Join(td, "fs") + if err = os.MkdirAll(fs, 0755); err != nil { return nil, err } @@ -297,6 +299,25 @@ func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshot.Kind, ke return nil, errors.Wrap(err, "failed to create active") } + if len(s.ParentIDs) > 0 { + st, err := os.Stat(filepath.Join(o.upperPath(s.ParentIDs[0]))) + if err != nil { + if rerr := t.Rollback(); rerr != nil { + log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction") + } + return nil, errors.Wrap(err, "failed to stat parent") + } + + stat := st.Sys().(*syscall.Stat_t) + + if err := os.Lchown(fs, int(stat.Uid), int(stat.Gid)); err != nil { + if rerr := t.Rollback(); rerr != nil { + log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction") + } + return nil, errors.Wrap(err, "failed to chown") + } + } + path = filepath.Join(snapshotDir, s.ID) if err = os.Rename(td, path); err != nil { if rerr := t.Rollback(); rerr != nil { diff --git a/spec_unix.go b/spec_unix.go index 39d182d41..a3b44c53b 100644 --- a/spec_unix.go +++ b/spec_unix.go @@ -171,9 +171,6 @@ func incrementFS(root string, uidInc, gidInc uint32) filepath.WalkFunc { if err != nil { return err } - if root == path { - return nil - } var ( stat = info.Sys().(*syscall.Stat_t) u, g = int(stat.Uid + uidInc), int(stat.Gid + gidInc)