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 <asarai@suse.de>
This commit is contained in:
parent
baeef29858
commit
f0876b0427
|
@ -4,38 +4,50 @@ package configs
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// HostUID gets the root uid for the process on host which could be non-zero
|
// HostUID gets the translated uid for the process on host which could be
|
||||||
// when user namespaces are enabled.
|
// different when user namespaces are enabled.
|
||||||
func (c Config) HostUID() (int, error) {
|
func (c Config) HostUID(containerId int) (int, error) {
|
||||||
if c.Namespaces.Contains(NEWUSER) {
|
if c.Namespaces.Contains(NEWUSER) {
|
||||||
if c.UidMappings == nil {
|
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 {
|
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 id, nil
|
||||||
}
|
}
|
||||||
// Return default root uid 0
|
// Return unchanged id.
|
||||||
return 0, nil
|
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.
|
// 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.Namespaces.Contains(NEWUSER) {
|
||||||
if c.GidMappings == nil {
|
if c.GidMappings == nil {
|
||||||
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
|
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 {
|
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 id, nil
|
||||||
}
|
}
|
||||||
// Return default root gid 0
|
// Return unchanged id.
|
||||||
return 0, nil
|
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
|
// Utility function that gets a host ID for a container ID from user namespace map
|
||||||
|
|
|
@ -65,11 +65,11 @@ func TestRemoveNamespace(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostUIDNoUSERNS(t *testing.T) {
|
func TestHostRootUIDNoUSERNS(t *testing.T) {
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Namespaces: Namespaces{},
|
Namespaces: Namespaces{},
|
||||||
}
|
}
|
||||||
uid, err := config.HostUID()
|
uid, err := config.HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func TestHostUIDNoUSERNS(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostUIDWithUSERNS(t *testing.T) {
|
func TestHostRootUIDWithUSERNS(t *testing.T) {
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Namespaces: Namespaces{{Type: NEWUSER}},
|
Namespaces: Namespaces{{Type: NEWUSER}},
|
||||||
UidMappings: []IDMap{
|
UidMappings: []IDMap{
|
||||||
|
@ -89,7 +89,7 @@ func TestHostUIDWithUSERNS(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
uid, err := config.HostUID()
|
uid, err := config.HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -98,11 +98,11 @@ func TestHostUIDWithUSERNS(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostGIDNoUSERNS(t *testing.T) {
|
func TestHostRootGIDNoUSERNS(t *testing.T) {
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Namespaces: Namespaces{},
|
Namespaces: Namespaces{},
|
||||||
}
|
}
|
||||||
uid, err := config.HostGID()
|
uid, err := config.HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ func TestHostGIDNoUSERNS(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostGIDWithUSERNS(t *testing.T) {
|
func TestHostRootGIDWithUSERNS(t *testing.T) {
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Namespaces: Namespaces{{Type: NEWUSER}},
|
Namespaces: Namespaces{{Type: NEWUSER}},
|
||||||
GidMappings: []IDMap{
|
GidMappings: []IDMap{
|
||||||
|
@ -122,7 +122,7 @@ func TestHostGIDWithUSERNS(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
uid, err := config.HostGID()
|
uid, err := config.HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (v *ConfigValidator) rootless(config *configs.Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func rootlessMappings(config *configs.Config) error {
|
func rootlessMappings(config *configs.Config) error {
|
||||||
rootuid, err := config.HostUID()
|
rootuid, err := config.HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get root uid from uidMappings: %v", err)
|
return fmt.Errorf("failed to get root uid from uidMappings: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func rootlessMappings(config *configs.Config) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootgid, err := config.HostGID()
|
rootgid, err := config.HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get root gid from gidMappings: %v", err)
|
return fmt.Errorf("failed to get root gid from gidMappings: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,11 +307,11 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *linuxContainer) createExecFifo() error {
|
func (c *linuxContainer) createExecFifo() error {
|
||||||
rootuid, err := c.Config().HostUID()
|
rootuid, err := c.Config().HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rootgid, err := c.Config().HostGID()
|
rootgid, err := c.Config().HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,11 +164,11 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||||
if err := l.Validator.Validate(config); err != nil {
|
if err := l.Validator.Validate(config); err != nil {
|
||||||
return nil, newGenericError(err, ConfigInvalid)
|
return nil, newGenericError(err, ConfigInvalid)
|
||||||
}
|
}
|
||||||
uid, err := config.HostUID()
|
uid, err := config.HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGenericError(err, SystemError)
|
return nil, newGenericError(err, SystemError)
|
||||||
}
|
}
|
||||||
gid, err := config.HostGID()
|
gid, err := config.HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newGenericError(err, SystemError)
|
return nil, newGenericError(err, SystemError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,11 +610,11 @@ func setupUserNamespace(spec *specs.Spec, config *configs.Config) error {
|
||||||
for _, m := range spec.Linux.GIDMappings {
|
for _, m := range spec.Linux.GIDMappings {
|
||||||
config.GidMappings = append(config.GidMappings, create(m))
|
config.GidMappings = append(config.GidMappings, create(m))
|
||||||
}
|
}
|
||||||
rootUID, err := config.HostUID()
|
rootUID, err := config.HostRootUID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rootGID, err := config.HostGID()
|
rootGID, err := config.HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,12 +242,12 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
||||||
for i := baseFd; i < baseFd+r.preserveFDs; i++ {
|
for i := baseFd; i < baseFd+r.preserveFDs; i++ {
|
||||||
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), "PreserveFD:"+strconv.Itoa(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 {
|
if err != nil {
|
||||||
r.destroy()
|
r.destroy()
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
rootgid, err := r.container.Config().HostGID()
|
rootgid, err := r.container.Config().HostRootGID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.destroy()
|
r.destroy()
|
||||||
return -1, err
|
return -1, err
|
||||||
|
|
Loading…
Reference in New Issue