diff --git a/mount/init.go b/mount/init.go index 10f07389..daec6ac8 100644 --- a/mount/init.go +++ b/mount/init.go @@ -11,7 +11,6 @@ import ( "github.com/docker/libcontainer/label" "github.com/docker/libcontainer/mount/nodes" "github.com/dotcloud/docker/pkg/symlink" - "github.com/dotcloud/docker/pkg/system" ) // default mount point flags @@ -35,10 +34,10 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) if mountConfig.NoPivotRoot { flag = syscall.MS_SLAVE } - if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { + if err := syscall.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil { return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err) } - if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { + if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } if err := mountSystem(rootfs, mountConfig); err != nil { @@ -56,7 +55,7 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) if err := setupDevSymlinks(rootfs); err != nil { return fmt.Errorf("dev symlinks %s", err) } - if err := system.Chdir(rootfs); err != nil { + if err := syscall.Chdir(rootfs); err != nil { return fmt.Errorf("chdir into %s %s", rootfs, err) } @@ -75,7 +74,7 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) } } - system.Umask(0022) + syscall.Umask(0022) return nil } @@ -87,7 +86,7 @@ func mountSystem(rootfs string, mountConfig *MountConfig) error { if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) { return fmt.Errorf("mkdirall %s %s", m.path, err) } - if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil { + if err := syscall.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil { return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err) } } @@ -169,11 +168,11 @@ func setupBindmounts(rootfs string, mountConfig *MountConfig) error { return fmt.Errorf("Creating new bind-mount target, %s", err) } - if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil { + if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil { return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err) } if !m.Writable { - if err := system.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil { + if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil { return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err) } } @@ -183,7 +182,7 @@ func setupBindmounts(rootfs string, mountConfig *MountConfig) error { } } if m.Private { - if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil { + if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil { return fmt.Errorf("mounting %s private %s", dest, err) } } diff --git a/mount/msmoveroot.go b/mount/msmoveroot.go index b336c864..94afd3a9 100644 --- a/mount/msmoveroot.go +++ b/mount/msmoveroot.go @@ -4,16 +4,17 @@ package mount import ( "fmt" - "github.com/dotcloud/docker/pkg/system" "syscall" ) func MsMoveRoot(rootfs string) error { - if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { + if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { return fmt.Errorf("mount move %s into / %s", rootfs, err) } - if err := system.Chroot("."); err != nil { + + if err := syscall.Chroot("."); err != nil { return fmt.Errorf("chroot . %s", err) } - return system.Chdir("/") + + return syscall.Chdir("/") } diff --git a/mount/nodes/nodes.go b/mount/nodes/nodes.go index e3420b48..6a984e33 100644 --- a/mount/nodes/nodes.go +++ b/mount/nodes/nodes.go @@ -9,13 +9,12 @@ import ( "syscall" "github.com/docker/libcontainer/devices" - "github.com/dotcloud/docker/pkg/system" ) // Create the device nodes in the container. func CreateDeviceNodes(rootfs string, nodesToCreate []*devices.Device) error { - oldMask := system.Umask(0000) - defer system.Umask(oldMask) + oldMask := syscall.Umask(0000) + defer syscall.Umask(oldMask) for _, node := range nodesToCreate { if err := CreateDeviceNode(rootfs, node); err != nil { @@ -46,7 +45,7 @@ func CreateDeviceNode(rootfs string, node *devices.Device) error { return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path) } - if err := system.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) { + if err := syscall.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) { return fmt.Errorf("mknod %s %s", node.Path, err) } return nil diff --git a/namespaces/exec.go b/namespaces/exec.go index bf297c08..ee87250e 100644 --- a/namespaces/exec.go +++ b/namespaces/exec.go @@ -14,7 +14,7 @@ import ( consolePkg "github.com/docker/libcontainer/console" "github.com/docker/libcontainer/network" "github.com/docker/libcontainer/syncpipe" - "github.com/dotcloud/docker/pkg/system" + "github.com/docker/libcontainer/system" ) // TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. diff --git a/namespaces/init.go b/namespaces/init.go index 4674944c..7c917c01 100644 --- a/namespaces/init.go +++ b/namespaces/init.go @@ -19,8 +19,8 @@ import ( "github.com/docker/libcontainer/security/capabilities" "github.com/docker/libcontainer/security/restrict" "github.com/docker/libcontainer/syncpipe" + "github.com/docker/libcontainer/system" "github.com/docker/libcontainer/utils" - "github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/pkg/user" ) @@ -57,7 +57,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn return err } } - if _, err := system.Setsid(); err != nil { + if _, err := syscall.Setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if consolePath != "" { @@ -81,7 +81,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn } if container.Hostname != "" { - if err := system.Sethostname(container.Hostname); err != nil { + if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { return fmt.Errorf("sethostname %s", err) } } @@ -155,15 +155,19 @@ func SetupUser(u string) error { if err != nil { return fmt.Errorf("get supplementary groups %s", err) } - if err := system.Setgroups(suppGids); err != nil { + + if err := syscall.Setgroups(suppGids); err != nil { return fmt.Errorf("setgroups %s", err) } - if err := system.Setgid(gid); err != nil { + + if err := syscall.Setgid(gid); err != nil { return fmt.Errorf("setgid %s", err) } - if err := system.Setuid(uid); err != nil { + + if err := syscall.Setuid(uid); err != nil { return fmt.Errorf("setuid %s", err) } + return nil } @@ -229,7 +233,7 @@ func FinalizeNamespace(container *libcontainer.Config) error { } if container.WorkingDir != "" { - if err := system.Chdir(container.WorkingDir); err != nil { + if err := syscall.Chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } diff --git a/security/restrict/restrict.go b/security/restrict/restrict.go index ff7ae2fe..dd765b1f 100644 --- a/security/restrict/restrict.go +++ b/security/restrict/restrict.go @@ -7,23 +7,21 @@ import ( "os" "syscall" "time" - - "github.com/dotcloud/docker/pkg/system" ) const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV func mountReadonly(path string) error { for i := 0; i < 5; i++ { - if err := system.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) { + if err := syscall.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) { switch err { case syscall.EINVAL: // Probably not a mountpoint, use bind-mount - if err := system.Mount(path, path, "", syscall.MS_BIND, ""); err != nil { + if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil { return err } - return system.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "") + return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "") case syscall.EBUSY: time.Sleep(100 * time.Millisecond) continue @@ -47,7 +45,7 @@ func Restrict(mounts ...string) error { } } - if err := system.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) { + if err := syscall.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) { return fmt.Errorf("unable to bind-mount /dev/null over /proc/kcore: %s", err) } diff --git a/selinux/selinux.go b/selinux/selinux.go index 709eb9d8..8dbdbdbc 100644 --- a/selinux/selinux.go +++ b/selinux/selinux.go @@ -5,8 +5,6 @@ import ( "crypto/rand" "encoding/binary" "fmt" - "github.com/dotcloud/docker/pkg/mount" - "github.com/dotcloud/docker/pkg/system" "io" "os" "path/filepath" @@ -14,6 +12,9 @@ import ( "strconv" "strings" "syscall" + + "github.com/docker/libcontainer/system" + "github.com/dotcloud/docker/pkg/mount" ) const ( @@ -153,16 +154,16 @@ func Getfilecon(path string) (string, error) { } func Setfscreatecon(scon string) error { - return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", system.Gettid()), scon) + return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), scon) } func Getfscreatecon() (string, error) { - return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", system.Gettid())) + return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid())) } // Return the SELinux label of the current process thread. func Getcon() (string, error) { - return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", system.Gettid())) + return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid())) } func Getpidcon(pid int) (string, error) { @@ -192,7 +193,7 @@ func writeCon(name string, val string) error { } func Setexeccon(scon string) error { - return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", system.Gettid()), scon) + return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), scon) } func (c SELinuxContext) Get() string { diff --git a/system/linux.go b/system/linux.go index 511b951a..c07ef153 100644 --- a/system/linux.go +++ b/system/linux.go @@ -5,6 +5,7 @@ package system import ( "os/exec" "syscall" + "unsafe" ) func Execv(cmd string, args []string, env []string) error { @@ -15,3 +16,45 @@ func Execv(cmd string, args []string, env []string) error { return syscall.Exec(name, args, env) } + +func ParentDeathSignal(sig uintptr) error { + if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 { + return err + } + return nil +} + +func GetParentDeathSignal() (int, error) { + var sig int + + _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0) + + if err != 0 { + return -1, err + } + + return sig, nil +} + +func SetKeepCaps() error { + if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 { + return err + } + + return nil +} + +func ClearKeepCaps() error { + if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 { + return err + } + + return nil +} + +func Setctty() error { + if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 { + return err + } + return nil +} diff --git a/system/xattrs_linux.go b/system/xattrs_linux.go new file mode 100644 index 00000000..00edb201 --- /dev/null +++ b/system/xattrs_linux.go @@ -0,0 +1,59 @@ +package system + +import ( + "syscall" + "unsafe" +) + +// Returns a nil slice and nil error if the xattr is not set +func Lgetxattr(path string, attr string) ([]byte, error) { + pathBytes, err := syscall.BytePtrFromString(path) + if err != nil { + return nil, err + } + attrBytes, err := syscall.BytePtrFromString(attr) + if err != nil { + return nil, err + } + + dest := make([]byte, 128) + destBytes := unsafe.Pointer(&dest[0]) + sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) + if errno == syscall.ENODATA { + return nil, nil + } + if errno == syscall.ERANGE { + dest = make([]byte, sz) + destBytes := unsafe.Pointer(&dest[0]) + sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) + } + if errno != 0 { + return nil, errno + } + + return dest[:sz], nil +} + +var _zero uintptr + +func Lsetxattr(path string, attr string, data []byte, flags int) error { + pathBytes, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + attrBytes, err := syscall.BytePtrFromString(attr) + if err != nil { + return err + } + var dataBytes unsafe.Pointer + if len(data) > 0 { + dataBytes = unsafe.Pointer(&data[0]) + } else { + dataBytes = unsafe.Pointer(&_zero) + } + _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) + if errno != 0 { + return errno + } + return nil +}