Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
libcontainer: configs: add proper HostUID and HostGID
Previously Host{U,G}ID only gave you the root mapping, which isn't very
useful if you are trying to do other things with the IDMaps.

Signed-off-by: Aleksa Sarai <[email protected]>
  • Loading branch information
cyphar committed Mar 23, 2017
commit f0876b04276226533b95e54c57e622f7d076f6f0
40 changes: 26 additions & 14 deletions libcontainer/configs/config_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,50 @@ package configs

import "fmt"

// HostUID gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostUID() (int, error) {
// HostUID gets the translated uid for the process on host which could be
// different when user namespaces are enabled.
func (c Config) HostUID(containerId int) (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.UidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
return -1, fmt.Errorf("User namespaces enabled, but no uid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.UidMappings)
id, found := c.hostIDFromMapping(containerId, c.UidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
return -1, fmt.Errorf("User namespaces enabled, but no user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
// Return unchanged id.
return containerId, nil
}

// HostGID gets the root gid for the process on host which could be non-zero
// HostRootUID gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostGID() (int, error) {
func (c Config) HostRootUID() (int, error) {
return c.HostUID(0)
}

// HostGID gets the translated gid for the process on host which could be
// different when user namespaces are enabled.
func (c Config) HostGID(containerId int) (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.GidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.GidMappings)
id, found := c.hostIDFromMapping(containerId, c.GidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root group mapping found.")
return -1, fmt.Errorf("User namespaces enabled, but no group mapping found.")
}
return id, nil
}
// Return default root gid 0
return 0, nil
// Return unchanged id.
return containerId, nil
}

// HostRootGID gets the root gid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostRootGID() (int, error) {
return c.HostGID(0)
}

// Utility function that gets a host ID for a container ID from user namespace map
Expand Down
16 changes: 8 additions & 8 deletions libcontainer/configs/config_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ func TestRemoveNamespace(t *testing.T) {
}
}

func TestHostUIDNoUSERNS(t *testing.T) {
func TestHostRootUIDNoUSERNS(t *testing.T) {
config := &Config{
Namespaces: Namespaces{},
}
uid, err := config.HostUID()
uid, err := config.HostRootUID()
if err != nil {
t.Fatal(err)
}
Expand All @@ -78,7 +78,7 @@ func TestHostUIDNoUSERNS(t *testing.T) {
}
}

func TestHostUIDWithUSERNS(t *testing.T) {
func TestHostRootUIDWithUSERNS(t *testing.T) {
config := &Config{
Namespaces: Namespaces{{Type: NEWUSER}},
UidMappings: []IDMap{
Expand All @@ -89,7 +89,7 @@ func TestHostUIDWithUSERNS(t *testing.T) {
},
},
}
uid, err := config.HostUID()
uid, err := config.HostRootUID()
if err != nil {
t.Fatal(err)
}
Expand All @@ -98,11 +98,11 @@ func TestHostUIDWithUSERNS(t *testing.T) {
}
}

func TestHostGIDNoUSERNS(t *testing.T) {
func TestHostRootGIDNoUSERNS(t *testing.T) {
config := &Config{
Namespaces: Namespaces{},
}
uid, err := config.HostGID()
uid, err := config.HostRootGID()
if err != nil {
t.Fatal(err)
}
Expand All @@ -111,7 +111,7 @@ func TestHostGIDNoUSERNS(t *testing.T) {
}
}

func TestHostGIDWithUSERNS(t *testing.T) {
func TestHostRootGIDWithUSERNS(t *testing.T) {
config := &Config{
Namespaces: Namespaces{{Type: NEWUSER}},
GidMappings: []IDMap{
Expand All @@ -122,7 +122,7 @@ func TestHostGIDWithUSERNS(t *testing.T) {
},
},
}
uid, err := config.HostGID()
uid, err := config.HostRootGID()
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/configs/validate/rootless.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (v *ConfigValidator) rootless(config *configs.Config) error {
}

func rootlessMappings(config *configs.Config) error {
rootuid, err := config.HostUID()
rootuid, err := config.HostRootUID()
if err != nil {
return fmt.Errorf("failed to get root uid from uidMappings: %v", err)
}
Expand All @@ -50,7 +50,7 @@ func rootlessMappings(config *configs.Config) error {
}
}

rootgid, err := config.HostGID()
rootgid, err := config.HostRootGID()
if err != nil {
return fmt.Errorf("failed to get root gid from gidMappings: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error {
}

func (c *linuxContainer) createExecFifo() error {
rootuid, err := c.Config().HostUID()
rootuid, err := c.Config().HostRootUID()
if err != nil {
return err
}
rootgid, err := c.Config().HostGID()
rootgid, err := c.Config().HostRootGID()
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/factory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
if err := l.Validator.Validate(config); err != nil {
return nil, newGenericError(err, ConfigInvalid)
}
uid, err := config.HostUID()
uid, err := config.HostRootUID()
if err != nil {
return nil, newGenericError(err, SystemError)
}
gid, err := config.HostGID()
gid, err := config.HostRootGID()
if err != nil {
return nil, newGenericError(err, SystemError)
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/specconv/spec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,11 +610,11 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
for _, m := range spec.Linux.GIDMappings {
config.GidMappings = append(config.GidMappings, create(m))
}
rootUID, err := config.HostUID()
rootUID, err := config.HostRootUID()
if err != nil {
return err
}
rootGID, err := config.HostGID()
rootGID, err := config.HostRootGID()
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions utils_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,12 @@ func (r *runner) run(config *specs.Process) (int, error) {
for i := baseFd; i < baseFd+r.preserveFDs; i++ {
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(i)))
}
rootuid, err := r.container.Config().HostUID()
rootuid, err := r.container.Config().HostRootUID()
if err != nil {
r.destroy()
return -1, err
}
rootgid, err := r.container.Config().HostGID()
rootgid, err := r.container.Config().HostRootGID()
if err != nil {
r.destroy()
return -1, err
Expand Down