From d9138069fe32b1ff113a4ee0fb22794a54ae3b03 Mon Sep 17 00:00:00 2001 From: "mengjiao.liu" Date: Wed, 3 Feb 2021 16:25:47 +0800 Subject: [PATCH] fix VolumeMount permissions with subpaths only apply the right permissions to the last directory --- pkg/volume/util/subpath/subpath_linux.go | 42 +++++++++---------- pkg/volume/util/subpath/subpath_linux_test.go | 11 +++++ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/pkg/volume/util/subpath/subpath_linux.go b/pkg/volume/util/subpath/subpath_linux.go index c04f0a78f37..1140f75ce5d 100644 --- a/pkg/volume/util/subpath/subpath_linux.go +++ b/pkg/volume/util/subpath/subpath_linux.go @@ -433,29 +433,29 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error { } parentFD = childFD childFD = -1 + + // Everything was created. mkdirat(..., perm) above was affected by current + // umask and we must apply the right permissions to the all created directory. + // (that's the one that will be available to the container as subpath) + // so user can read/write it. + // parentFD is the last created directory. + + // Translate perm (os.FileMode) to uint32 that fchmod() expects + kernelPerm := uint32(perm & os.ModePerm) + if perm&os.ModeSetgid > 0 { + kernelPerm |= syscall.S_ISGID + } + if perm&os.ModeSetuid > 0 { + kernelPerm |= syscall.S_ISUID + } + if perm&os.ModeSticky > 0 { + kernelPerm |= syscall.S_ISVTX + } + if err = syscall.Fchmod(parentFD, kernelPerm); err != nil { + return fmt.Errorf("chmod %q failed: %s", currentPath, err) + } } - // Everything was created. mkdirat(..., perm) above was affected by current - // umask and we must apply the right permissions to the last directory - // (that's the one that will be available to the container as subpath) - // so user can read/write it. This is the behavior of previous code. - // TODO: chmod all created directories, not just the last one. - // parentFD is the last created directory. - - // Translate perm (os.FileMode) to uint32 that fchmod() expects - kernelPerm := uint32(perm & os.ModePerm) - if perm&os.ModeSetgid > 0 { - kernelPerm |= syscall.S_ISGID - } - if perm&os.ModeSetuid > 0 { - kernelPerm |= syscall.S_ISUID - } - if perm&os.ModeSticky > 0 { - kernelPerm |= syscall.S_ISVTX - } - if err = syscall.Fchmod(parentFD, kernelPerm); err != nil { - return fmt.Errorf("chmod %q failed: %s", currentPath, err) - } return nil } diff --git a/pkg/volume/util/subpath/subpath_linux_test.go b/pkg/volume/util/subpath/subpath_linux_test.go index 00a54e501ec..d7f54491393 100644 --- a/pkg/volume/util/subpath/subpath_linux_test.go +++ b/pkg/volume/util/subpath/subpath_linux_test.go @@ -35,6 +35,7 @@ import ( func TestSafeMakeDir(t *testing.T) { defaultPerm := os.FileMode(0750) + os.ModeDir + maxPerm := os.FileMode(0777) + os.ModeDir tests := []struct { name string // Function that prepares directory structure for the test under given @@ -55,6 +56,16 @@ func TestSafeMakeDir(t *testing.T) { defaultPerm, false, }, + { + "all-created-subpath-directory-with-permissions", + func(base string) error { + return nil + }, + "test/directory", + "test", + maxPerm, + false, + }, { "directory-with-sgid", func(base string) error {