From 76bb43027b0ff3dac61dd9721591c42af9afcbdf Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Mon, 7 Aug 2017 14:28:38 +0100 Subject: [PATCH] Do an extra chmod after chown Chown clears suid bits even for root on Linux. Also move a few functions to x/sys/unix from syscall, to be more arm64 friendly. Signed-off-by: Justin Cormack --- pkg/init/init.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/init/init.go b/pkg/init/init.go index 714b17f57..8f80f6834 100644 --- a/pkg/init/init.go +++ b/pkg/init/init.go @@ -22,13 +22,19 @@ import ( func copyMetadata(info os.FileInfo, path string) error { // would rather use fd than path but Go makes this very difficult at present stat := info.Sys().(*syscall.Stat_t) - if err := syscall.Lchown(path, int(stat.Uid), int(stat.Gid)); err != nil { + if err := unix.Lchown(path, int(stat.Uid), int(stat.Gid)); err != nil { return err } timespec := []unix.Timespec{unix.Timespec(stat.Atim), unix.Timespec(stat.Mtim)} if err := unix.UtimesNanoAt(unix.AT_FDCWD, path, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil { return err } + // after chown suid bits may be dropped; re-set on non symlink files + if info.Mode()&os.ModeSymlink == 0 { + if err := os.Chmod(path, info.Mode()); err != nil { + return err + } + } return nil } @@ -41,7 +47,7 @@ func copyFS(newRoot string) error { stat := info.Sys().(*syscall.Stat_t) rootDev := stat.Dev - if err = syscall.Mount("rootfs", newRoot, "tmpfs", 0, ""); err != nil { + if err = unix.Mount("rootfs", newRoot, "tmpfs", 0, ""); err != nil { return err } @@ -126,7 +132,7 @@ func copyFS(newRoot string) error { return err } case (info.Mode() & os.ModeDevice) == os.ModeDevice: - if err := syscall.Mknod(dest, uint32(info.Mode()), int(stat.Rdev)); err != nil { + if err := unix.Mknod(dest, uint32(info.Mode()), int(stat.Rdev)); err != nil { return err } case (info.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe: @@ -180,12 +186,12 @@ func copyFS(newRoot string) error { } // mount --move cwd (/mnt) to / - if err := syscall.Mount(".", "/", "", syscall.MS_MOVE, ""); err != nil { + if err := unix.Mount(".", "/", "", unix.MS_MOVE, ""); err != nil { return err } // chroot to . - if err := syscall.Chroot("."); err != nil { + if err := unix.Chroot("."); err != nil { return err } @@ -200,8 +206,8 @@ func copyFS(newRoot string) error { func main() { // test if we want to do this, ie if tmpfs or ramfs // we could be booting off ISO, disk where we do not need this - var sfs syscall.Statfs_t - if err := syscall.Statfs("/", &sfs); err != nil { + var sfs unix.Statfs_t + if err := unix.Statfs("/", &sfs); err != nil { log.Fatalf("Cannot statfs /: %v", err) } const ramfsMagic = 0x858458f6