[lxc-devel] [lxd/master] Bugfixes

stgraber on Github lxc-bot at linuxcontainers.org
Fri Feb 24 00:45:59 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170224/f3fa74e3/attachment.bin>
-------------- next part --------------
From 3cee68ae69df77b922680d3def03a786728c99d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 23 Feb 2017 18:08:45 -0500
Subject: [PATCH 1/4] idmap: Drop GetOwner
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/idmapset_linux.go | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/shared/idmapset_linux.go b/shared/idmapset_linux.go
index 8a3ebf3..b2784ab 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmapset_linux.go
@@ -319,11 +319,6 @@ func (m IdmapSet) ShiftFromNs(uid int, gid int) (int, int) {
 	return m.doShiftIntoNs(uid, gid, "out")
 }
 
-func GetOwner(path string) (int, int, error) {
-	uid, gid, _, _, _, _, err := GetFileStat(path)
-	return uid, gid, err
-}
-
 func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error {
 	// Expand any symlink before the final path component
 	tmp := filepath.Dir(dir)
@@ -335,7 +330,7 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
 	dir = strings.TrimRight(dir, "/")
 
 	convert := func(path string, fi os.FileInfo, err error) (e error) {
-		uid, gid, err := GetOwner(path)
+		uid, gid, _, _, _, _, err := GetFileStat(path)
 		if err != nil {
 			return err
 		}

From ea711b7a191c4aaaf471fdf132034e9af189fa08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 23 Feb 2017 18:33:47 -0500
Subject: [PATCH 2/4] Remove debugging during idmap changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 336d3db..8e93cad 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1572,7 +1572,7 @@ func (c *containerLXC) startCommon() (string, error) {
 	}
 
 	if !reflect.DeepEqual(idmap, lastIdmap) {
-		shared.LogDebugf("Container idmap changed, remapping: %s => %s", lastIdmap, idmap)
+		shared.LogDebugf("Container idmap changed, remapping")
 
 		err := c.StorageStart()
 		if err != nil {

From 8b8aa238a3ba94d5d77d7f00ec4053d3e880c460 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 23 Feb 2017 19:44:40 -0500
Subject: [PATCH 3/4] idmap: Implement Usable() functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/idmapset_linux.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/shared/idmapset_linux.go b/shared/idmapset_linux.go
index b2784ab..6565842 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmapset_linux.go
@@ -7,10 +7,22 @@ import (
 	"os/exec"
 	"path"
 	"path/filepath"
+	"sort"
 	"strconv"
 	"strings"
 )
 
+type IdRange struct {
+	Isuid   bool
+	Isgid   bool
+	Startid int
+	Endid   int
+}
+
+func (i *IdRange) Contains(id int) bool {
+	return id >= i.Startid && id <= i.Endid
+}
+
 /*
  * One entry in id mapping set - a single range of either
  * uid or gid mappings.
@@ -83,6 +95,40 @@ func (e *IdmapEntry) Intersects(i IdmapEntry) bool {
 	return false
 }
 
+func (e *IdmapEntry) Usable() error {
+	kernelIdmap, err := CurrentIdmapSet()
+	if err != nil {
+		return err
+	}
+
+	kernelRanges, err := kernelIdmap.ValidRanges()
+	if err != nil {
+		return err
+	}
+
+	valid := false
+	for _, kernelRange := range kernelRanges {
+		if kernelRange.Isuid != e.Isuid {
+			continue
+		}
+
+		if kernelRange.Isgid != e.Isgid {
+			continue
+		}
+
+		if kernelRange.Contains(e.Hostid) && kernelRange.Contains(e.Hostid+e.Maprange-1) {
+			valid = true
+			break
+		}
+	}
+
+	if !valid {
+		return fmt.Errorf("The '%s' map can't work in the current user namespace.", e.ToLxcString())
+	}
+
+	return nil
+}
+
 func (e *IdmapEntry) parse(s string) error {
 	split := strings.Split(s, ":")
 	var err error
@@ -184,6 +230,22 @@ func (m IdmapSet) Len() int {
 	return len(m.Idmap)
 }
 
+func (m IdmapSet) Swap(i, j int) {
+	m.Idmap[i], m.Idmap[j] = m.Idmap[j], m.Idmap[i]
+}
+
+func (m IdmapSet) Less(i, j int) bool {
+	if m.Idmap[i].Isuid != m.Idmap[j].Isuid {
+		return m.Idmap[i].Isuid == true
+	}
+
+	if m.Idmap[i].Isgid != m.Idmap[j].Isgid {
+		return m.Idmap[i].Isgid == true
+	}
+
+	return m.Idmap[i].Nsid < m.Idmap[j].Nsid
+}
+
 func (m IdmapSet) Intersects(i IdmapEntry) bool {
 	for _, e := range m.Idmap {
 		if i.Intersects(e) {
@@ -202,6 +264,57 @@ func (m IdmapSet) HostidsIntersect(i IdmapEntry) bool {
 	return false
 }
 
+func (m IdmapSet) Usable() error {
+	for _, e := range m.Idmap {
+		err := e.Usable()
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (m IdmapSet) ValidRanges() ([]*IdRange, error) {
+	ranges := []*IdRange{}
+
+	// Sort the map
+	idmap := IdmapSet{}
+	err := DeepCopy(&m, &idmap)
+	if err != nil {
+		return nil, err
+	}
+	sort.Sort(idmap)
+
+	for _, mapEntry := range idmap.Idmap {
+		var entry *IdRange
+		for _, idEntry := range ranges {
+			if mapEntry.Isuid != idEntry.Isuid || mapEntry.Isgid != idEntry.Isgid {
+				continue
+			}
+
+			if idEntry.Endid+1 == mapEntry.Nsid {
+				entry = idEntry
+				break
+			}
+		}
+
+		if entry != nil {
+			entry.Endid = entry.Endid + mapEntry.Maprange
+			continue
+		}
+
+		ranges = append(ranges, &IdRange{
+			Isuid:   mapEntry.Isuid,
+			Isgid:   mapEntry.Isgid,
+			Startid: mapEntry.Nsid,
+			Endid:   mapEntry.Nsid + mapEntry.Maprange - 1,
+		})
+	}
+
+	return ranges, nil
+}
+
 /* AddSafe adds an entry to the idmap set, breaking apart any ranges that the
  * new idmap intersects with in the process.
  */

From 4d9832d21142bca9a372df5c4474835c01072c96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 23 Feb 2017 19:44:54 -0500
Subject: [PATCH 4/4] Check for the validity of the id maps at startup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #2885

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/daemon.go | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index dc3d0ab..0cf27ab 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -798,12 +798,36 @@ func (d *Daemon) Init() error {
 	/* Read the uid/gid allocation */
 	d.IdmapSet, err = shared.DefaultIdmapSet()
 	if err != nil {
-		shared.LogWarn("Error reading idmap", log.Ctx{"err": err.Error()})
+		shared.LogWarn("Error reading default idmap", log.Ctx{"err": err.Error()})
 		shared.LogWarnf("Only privileged containers will be able to run")
+		d.IdmapSet = nil
 	} else {
-		shared.LogInfof("Available uid/gid map:")
-		for _, lxcmap := range d.IdmapSet.ToLxcString() {
-			shared.LogInfof(strings.TrimRight(" - "+lxcmap, "\n"))
+		kernelIdmapSet, err := shared.CurrentIdmapSet()
+		if err == nil {
+			shared.LogInfof("Kernel uid/gid map:")
+			for _, lxcmap := range kernelIdmapSet.ToLxcString() {
+				shared.LogInfof(strings.TrimRight(" - "+lxcmap, "\n"))
+			}
+		}
+
+		shared.LogInfof("Configured LXD uid/gid map:")
+		for _, lxcmap := range d.IdmapSet.Idmap {
+			suffix := ""
+
+			if lxcmap.Usable() != nil {
+				suffix = " (unusable)"
+			}
+
+			for _, lxcEntry := range lxcmap.ToLxcString() {
+				shared.LogInfof(" - %s%s", strings.TrimRight(lxcEntry, "\n"), suffix)
+			}
+		}
+
+		err = d.IdmapSet.Usable()
+		if err != nil {
+			shared.LogWarnf("One or more uid/gid map entry isn't usable (typically due to nesting)")
+			shared.LogWarnf("Only privileged containers will be able to run")
+			d.IdmapSet = nil
 		}
 	}
 


More information about the lxc-devel mailing list