summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/chrootuser/user.go6
-rw-r--r--pkg/chrootuser/user_linux.go4
-rw-r--r--pkg/rootless/rootless.go104
-rw-r--r--pkg/rootless/rootless_linux.go117
-rw-r--r--pkg/rootless/rootless_unsupported.go18
-rw-r--r--pkg/spec/config_linux.go84
-rw-r--r--pkg/spec/config_unsupported.go12
-rw-r--r--pkg/spec/createconfig.go17
-rw-r--r--pkg/spec/parse.go15
-rw-r--r--pkg/spec/spec.go43
10 files changed, 243 insertions, 177 deletions
diff --git a/pkg/chrootuser/user.go b/pkg/chrootuser/user.go
index 1fbb5566e..3de138b86 100644
--- a/pkg/chrootuser/user.go
+++ b/pkg/chrootuser/user.go
@@ -8,6 +8,12 @@ import (
"github.com/pkg/errors"
)
+var (
+ // ErrNoSuchUser indicates that the user provided by the caller does not
+ // exist in /etc/passws
+ ErrNoSuchUser = errors.New("user does not exist in /etc/passwd")
+)
+
// GetUser will return the uid, gid of the user specified in the userspec
// it will use the /etc/passwd and /etc/group files inside of the rootdir
// to return this information.
diff --git a/pkg/chrootuser/user_linux.go b/pkg/chrootuser/user_linux.go
index d48a1c7c2..acd0af822 100644
--- a/pkg/chrootuser/user_linux.go
+++ b/pkg/chrootuser/user_linux.go
@@ -4,7 +4,6 @@ package chrootuser
import (
"bufio"
- "errors"
"flag"
"fmt"
"io"
@@ -79,9 +78,6 @@ func openChrootedFile(rootdir, filename string) (*exec.Cmd, io.ReadCloser, error
var (
lookupUser, lookupGroup sync.Mutex
- // ErrNoSuchUser indicates that the user provided by the caller does not
- // exist in /etc/passws
- ErrNoSuchUser = errors.New("user does not exist in /etc/passwd")
)
type lookupPasswdEntry struct {
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
index 737fc91c7..ca851f9bc 100644
--- a/pkg/rootless/rootless.go
+++ b/pkg/rootless/rootless.go
@@ -2,16 +2,9 @@ package rootless
import (
"fmt"
- "io/ioutil"
+ "github.com/containers/storage/pkg/idtools"
"os"
"os/exec"
- gosignal "os/signal"
- "runtime"
- "syscall"
-
- "github.com/containers/storage/pkg/idtools"
- "github.com/docker/docker/pkg/signal"
- "github.com/pkg/errors"
)
/*
@@ -25,11 +18,6 @@ func runInUser() error {
return nil
}
-// IsRootless tells us if we are running in rootless mode
-func IsRootless() bool {
- return os.Getuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != ""
-}
-
func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap) error {
path, err := exec.LookPath(tool)
if err != nil {
@@ -53,93 +41,3 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
}
return cmd.Run()
}
-
-// BecomeRootInUserNS re-exec podman in a new userNS
-func BecomeRootInUserNS() (bool, error) {
-
- if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
- if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
- return false, runInUser()
- }
- return false, nil
- }
-
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
-
- r, w, err := os.Pipe()
- if err != nil {
- return false, err
- }
- defer r.Close()
- defer w.Close()
-
- pidC := C.reexec_in_user_namespace(C.int(r.Fd()))
- pid := int(pidC)
- if pid < 0 {
- return false, errors.Errorf("cannot re-exec process")
- }
-
- setgroups := fmt.Sprintf("/proc/%d/setgroups", pid)
- err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666)
- if err != nil {
- return false, errors.Wrapf(err, "cannot write setgroups file")
- }
-
- var uids, gids []idtools.IDMap
- username := os.Getenv("USER")
- mappings, err := idtools.NewIDMappings(username, username)
- if err == nil {
- uids = mappings.UIDs()
- gids = mappings.GIDs()
- }
-
- uidsMapped := false
- if mappings != nil && uids != nil {
- uidsMapped = tryMappingTool("newuidmap", pid, os.Getuid(), uids) == nil
- }
- if !uidsMapped {
- uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
- err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getuid())), 0666)
- if err != nil {
- return false, errors.Wrapf(err, "cannot write uid_map")
- }
- }
-
- gidsMapped := false
- if mappings != nil && gids != nil {
- gidsMapped = tryMappingTool("newgidmap", pid, os.Getgid(), gids) == nil
- }
- if !gidsMapped {
- gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
- err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getgid())), 0666)
- if err != nil {
- return false, errors.Wrapf(err, "cannot write gid_map")
- }
- }
-
- _, err = w.Write([]byte("1"))
- if err != nil {
- return false, errors.Wrapf(err, "write to sync pipe")
- }
-
- c := make(chan os.Signal, 1)
-
- gosignal.Notify(c)
- defer gosignal.Reset()
- go func() {
- for s := range c {
- if s == signal.SIGCHLD || s == signal.SIGPIPE {
- continue
- }
-
- syscall.Kill(int(pidC), s.(syscall.Signal))
- }
- }()
-
- if C.reexec_in_user_namespace_wait(pidC) < 0 {
- return false, errors.Wrapf(err, "error waiting for the re-exec process")
- }
-
- return true, nil
-}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
new file mode 100644
index 000000000..5b4094bf2
--- /dev/null
+++ b/pkg/rootless/rootless_linux.go
@@ -0,0 +1,117 @@
+// build +linux
+
+package rootless
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ gosignal "os/signal"
+ "runtime"
+ "syscall"
+
+ "github.com/containers/storage/pkg/idtools"
+ "github.com/docker/docker/pkg/signal"
+ "github.com/pkg/errors"
+)
+
+/*
+extern int reexec_in_user_namespace(int ready);
+extern int reexec_in_user_namespace_wait(int pid);
+*/
+import "C"
+
+// IsRootless tells us if we are running in rootless mode
+func IsRootless() bool {
+ return os.Getuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != ""
+}
+
+// BecomeRootInUserNS re-exec podman in a new userNS
+func BecomeRootInUserNS() (bool, error) {
+
+ if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
+ if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
+ return false, runInUser()
+ }
+ return false, nil
+ }
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ r, w, err := os.Pipe()
+ if err != nil {
+ return false, err
+ }
+ defer r.Close()
+ defer w.Close()
+
+ pidC := C.reexec_in_user_namespace(C.int(r.Fd()))
+ pid := int(pidC)
+ if pid < 0 {
+ return false, errors.Errorf("cannot re-exec process")
+ }
+
+ setgroups := fmt.Sprintf("/proc/%d/setgroups", pid)
+ err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666)
+ if err != nil {
+ return false, errors.Wrapf(err, "cannot write setgroups file")
+ }
+
+ var uids, gids []idtools.IDMap
+ username := os.Getenv("USER")
+ mappings, err := idtools.NewIDMappings(username, username)
+ if err == nil {
+ uids = mappings.UIDs()
+ gids = mappings.GIDs()
+ }
+
+ uidsMapped := false
+ if mappings != nil && uids != nil {
+ uidsMapped = tryMappingTool("newuidmap", pid, os.Getuid(), uids) == nil
+ }
+ if !uidsMapped {
+ uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
+ err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getuid())), 0666)
+ if err != nil {
+ return false, errors.Wrapf(err, "cannot write uid_map")
+ }
+ }
+
+ gidsMapped := false
+ if mappings != nil && gids != nil {
+ gidsMapped = tryMappingTool("newgidmap", pid, os.Getgid(), gids) == nil
+ }
+ if !gidsMapped {
+ gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
+ err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getgid())), 0666)
+ if err != nil {
+ return false, errors.Wrapf(err, "cannot write gid_map")
+ }
+ }
+
+ _, err = w.Write([]byte("1"))
+ if err != nil {
+ return false, errors.Wrapf(err, "write to sync pipe")
+ }
+
+ c := make(chan os.Signal, 1)
+
+ gosignal.Notify(c)
+ defer gosignal.Reset()
+ go func() {
+ for s := range c {
+ if s == signal.SIGCHLD || s == signal.SIGPIPE {
+ continue
+ }
+
+ syscall.Kill(int(pidC), s.(syscall.Signal))
+ }
+ }()
+
+ if C.reexec_in_user_namespace_wait(pidC) < 0 {
+ return false, errors.Wrapf(err, "error waiting for the re-exec process")
+ }
+
+ return true, nil
+}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
new file mode 100644
index 000000000..e4067a764
--- /dev/null
+++ b/pkg/rootless/rootless_unsupported.go
@@ -0,0 +1,18 @@
+// +build !linux
+
+package rootless
+
+import (
+ "github.com/pkg/errors"
+)
+
+// IsRootless returns false on all non-linux platforms
+func IsRootless() bool {
+ return false
+}
+
+// BecomeRootInUserNS is a stub function that always returns false and an
+// error on unsupported OS's
+func BecomeRootInUserNS() (bool, error) {
+ return false, errors.New("this function is not supported on this os")
+}
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
new file mode 100644
index 000000000..69b99232f
--- /dev/null
+++ b/pkg/spec/config_linux.go
@@ -0,0 +1,84 @@
+// +build linux
+
+package createconfig
+
+import (
+ "io/ioutil"
+
+ "github.com/docker/docker/profiles/seccomp"
+ "github.com/opencontainers/runc/libcontainer/configs"
+ "github.com/opencontainers/runc/libcontainer/devices"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/opencontainers/runtime-tools/generate"
+ "github.com/pkg/errors"
+)
+
+// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
+func Device(d *configs.Device) spec.LinuxDevice {
+ return spec.LinuxDevice{
+ Type: string(d.Type),
+ Path: d.Path,
+ Major: d.Major,
+ Minor: d.Minor,
+ FileMode: fmPtr(int64(d.FileMode)),
+ UID: u32Ptr(int64(d.Uid)),
+ GID: u32Ptr(int64(d.Gid)),
+ }
+}
+
+func addDevice(g *generate.Generator, device string) error {
+ dev, err := devices.DeviceFromPath(device, "rwm")
+ if err != nil {
+ return errors.Wrapf(err, "%s is not a valid device", device)
+ }
+ linuxdev := spec.LinuxDevice{
+ Path: dev.Path,
+ Type: string(dev.Type),
+ Major: dev.Major,
+ Minor: dev.Minor,
+ FileMode: &dev.FileMode,
+ UID: &dev.Uid,
+ GID: &dev.Gid,
+ }
+ g.AddDevice(linuxdev)
+ g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions)
+ return nil
+}
+
+// AddPrivilegedDevices iterates through host devices and adds all
+// host devices to the spec
+func (c *CreateConfig) AddPrivilegedDevices(g *generate.Generator) error {
+ hostDevices, err := devices.HostDevices()
+ if err != nil {
+ return err
+ }
+ g.ClearLinuxDevices()
+ for _, d := range hostDevices {
+ g.AddDevice(Device(d))
+ }
+ g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
+ return nil
+}
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+ var seccompConfig *spec.LinuxSeccomp
+ var err error
+
+ if config.SeccompProfilePath != "" {
+ seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ seccompConfig, err = seccomp.LoadProfile(string(seccompProfile), configSpec)
+ if err != nil {
+ return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ } else {
+ seccompConfig, err = seccomp.GetDefaultProfile(configSpec)
+ if err != nil {
+ return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ }
+
+ return seccompConfig, nil
+}
diff --git a/pkg/spec/config_unsupported.go b/pkg/spec/config_unsupported.go
new file mode 100644
index 000000000..b3b05acea
--- /dev/null
+++ b/pkg/spec/config_unsupported.go
@@ -0,0 +1,12 @@
+// +build !linux
+
+package createconfig
+
+import (
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/pkg/errors"
+)
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+ return nil, errors.New("function not supported on non-linux OS's")
+}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 27df0c395..451c09eb3 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -10,9 +10,7 @@ import (
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
- "github.com/opencontainers/runc/libcontainer/devices"
spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/libpod"
@@ -488,21 +486,6 @@ func (c *CreateConfig) CreatePortBindings() ([]ocicni.PortMapping, error) {
return portBindings, nil
}
-// AddPrivilegedDevices iterates through host devices and adds all
-// host devices to the spec
-func (c *CreateConfig) AddPrivilegedDevices(g *generate.Generator) error {
- hostDevices, err := devices.HostDevices()
- if err != nil {
- return err
- }
- g.ClearLinuxDevices()
- for _, d := range hostDevices {
- g.AddDevice(Device(d))
- }
- g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
- return nil
-}
-
func getStatFromPath(path string) (unix.Stat_t, error) {
s := unix.Stat_t{}
err := unix.Stat(path, &s)
diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go
index 920674b10..82ca92dff 100644
--- a/pkg/spec/parse.go
+++ b/pkg/spec/parse.go
@@ -6,8 +6,6 @@ import (
"strings"
"github.com/docker/go-units"
- "github.com/opencontainers/runc/libcontainer/configs"
- spec "github.com/opencontainers/runtime-spec/specs-go"
)
// weightDevice is a structure that holds device:weight pair
@@ -113,16 +111,3 @@ func getLoggingPath(opts []string) string {
}
return ""
}
-
-// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
-func Device(d *configs.Device) spec.LinuxDevice {
- return spec.LinuxDevice{
- Type: string(d.Type),
- Path: d.Path,
- Major: d.Major,
- Minor: d.Minor,
- FileMode: fmPtr(int64(d.FileMode)),
- UID: u32Ptr(int64(d.Uid)),
- GID: u32Ptr(int64(d.Gid)),
- }
-}
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 2faa3c2cd..f9c60fdfa 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -6,14 +6,11 @@ import (
"github.com/docker/docker/daemon/caps"
"github.com/docker/docker/pkg/mount"
"github.com/docker/go-units"
- "github.com/opencontainers/runc/libcontainer/devices"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/pkg/rootless"
- seccomp "github.com/seccomp/containers-golang"
"github.com/sirupsen/logrus"
- "io/ioutil"
)
const cpuPeriod = 100000
@@ -236,24 +233,13 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
}
// HANDLE SECCOMP
+
if config.SeccompProfilePath != "unconfined" {
- if config.SeccompProfilePath != "" {
- seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
- if err != nil {
- return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- seccompConfig, err := seccomp.LoadProfile(string(seccompProfile), configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- configSpec.Linux.Seccomp = seccompConfig
- } else {
- seccompConfig, err := seccomp.GetDefaultProfile(configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- configSpec.Linux.Seccomp = seccompConfig
+ seccompConfig, err := getSeccompConfig(config, configSpec)
+ if err != nil {
+ return nil, err
}
+ configSpec.Linux.Seccomp = seccompConfig
}
// Clear default Seccomp profile from Generator for privileged containers
@@ -429,22 +415,3 @@ func setupCapabilities(config *CreateConfig, configSpec *spec.Spec) error {
configSpec.Process.Capabilities.Bounding = caplist
return nil
}
-
-func addDevice(g *generate.Generator, device string) error {
- dev, err := devices.DeviceFromPath(device, "rwm")
- if err != nil {
- return errors.Wrapf(err, "%s is not a valid device", device)
- }
- linuxdev := spec.LinuxDevice{
- Path: dev.Path,
- Type: string(dev.Type),
- Major: dev.Major,
- Minor: dev.Minor,
- FileMode: &dev.FileMode,
- UID: &dev.Uid,
- GID: &dev.Gid,
- }
- g.AddDevice(linuxdev)
- g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions)
- return nil
-}