[lxc-devel] [lxd/master] Bugfixes

stgraber on Github lxc-bot at linuxcontainers.org
Mon Feb 27 21:51:41 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/20170227/cd69b73a/attachment.bin>
-------------- next part --------------
From 22176fb5343c0fb9393937ab3004c94f2d30afc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 27 Feb 2017 15:59:52 -0500
Subject: [PATCH 1/5] Fix uint32 check
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/container.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shared/container.go b/shared/container.go
index 34363c4..038a7cb 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -34,7 +34,7 @@ func IsUint32(value string) error {
 		return nil
 	}
 
-	_, err := strconv.ParseInt(value, 10, 32)
+	_, err := strconv.ParseUint(value, 10, 32)
 	if err != nil {
 		return fmt.Errorf("Invalid value for uint32: %s: %v", value, err)
 	}

From 67bc302ee6838901dde79f0fa81962747d875af4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 27 Feb 2017 16:02:49 -0500
Subject: [PATCH 2/5] Don't parse id ranges as int32
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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index d172e8a..09100b1 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -464,12 +464,12 @@ func idmapSize(daemon *Daemon, isolatedStr string, size string) (int64, error) {
 			idMapSize = daemon.IdmapSet.Idmap[0].Maprange
 		}
 	} else {
-		size, err := strconv.ParseInt(size, 10, 32)
+		size, err := strconv.ParseInt(size, 10, 64)
 		if err != nil {
 			return 0, err
 		}
 
-		idMapSize = int64(size)
+		idMapSize = size
 	}
 
 	return idMapSize, nil
@@ -621,7 +621,7 @@ func findIdmap(daemon *Daemon, cName string, isolatedStr string, configSize stri
 
 		cBase := int64(0)
 		if container.ExpandedConfig()["volatile.idmap.base"] != "" {
-			cBase, err = strconv.ParseInt(container.ExpandedConfig()["volatile.idmap.base"], 10, 32)
+			cBase, err = strconv.ParseInt(container.ExpandedConfig()["volatile.idmap.base"], 10, 64)
 			if err != nil {
 				return nil, 0, err
 			}

From 0fff6cd3504b19d5a02374af65b631e5d4a613ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 27 Feb 2017 16:04:19 -0500
Subject: [PATCH 3/5] Clarify uid/gid error
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 09100b1..dd86bd8 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -676,7 +676,7 @@ func findIdmap(daemon *Daemon, cName string, isolatedStr string, configSize stri
 		return mkIdmap(offset, size), offset, nil
 	}
 
-	return nil, 0, fmt.Errorf("no map range available")
+	return nil, 0, fmt.Errorf("Not enough uid/gid available for the container.")
 }
 
 func (c *containerLXC) init() error {

From fc489d29d69af4e62e20dce6aff8714021ee56e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 27 Feb 2017 16:34:08 -0500
Subject: [PATCH 4/5] idmap: Make more of an effort to find a default
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/daemon.go            | 36 ++++++++++++----------
 shared/idmapset_linux.go | 77 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index 9c77fce..0c79406 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -798,7 +798,7 @@ func (d *Daemon) Init() error {
 	/* Read the uid/gid allocation */
 	d.IdmapSet, err = shared.DefaultIdmapSet()
 	if err != nil {
-		shared.LogWarn("Error reading default idmap", log.Ctx{"err": err.Error()})
+		shared.LogWarn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
 		shared.LogWarnf("Only privileged containers will be able to run")
 		d.IdmapSet = nil
 	} else {
@@ -810,24 +810,30 @@ func (d *Daemon) Init() error {
 			}
 		}
 
-		shared.LogInfof("Configured LXD uid/gid map:")
-		for _, lxcmap := range d.IdmapSet.Idmap {
-			suffix := ""
+		if len(d.IdmapSet.Idmap) == 0 {
+			shared.LogWarnf("No available uid/gid map could be found")
+			shared.LogWarnf("Only privileged containers will be able to run")
+			d.IdmapSet = nil
+		} else {
+			shared.LogInfof("Configured LXD uid/gid map:")
+			for _, lxcmap := range d.IdmapSet.Idmap {
+				suffix := ""
 
-			if lxcmap.Usable() != nil {
-				suffix = " (unusable)"
-			}
+				if lxcmap.Usable() != nil {
+					suffix = " (unusable)"
+				}
 
-			for _, lxcEntry := range lxcmap.ToLxcString() {
-				shared.LogInfof(" - %s%s", strings.TrimRight(lxcEntry, "\n"), suffix)
+				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
+			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
+			}
 		}
 	}
 
diff --git a/shared/idmapset_linux.go b/shared/idmapset_linux.go
index 9e39f27..d08970e 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmapset_linux.go
@@ -658,10 +658,83 @@ func DefaultIdmapSet() (*IdmapSet, error) {
 			// NOTE: Remove once LXD can deal with multiple shadow maps
 			break
 		}
-	} else {
-		// Fallback map
+
+		return idmapset, nil
+	}
+
+	// No shadow available, figure out a default map
+	kernelMap, err := CurrentIdmapSet()
+	if err != nil {
+		// Hardcoded fallback map
 		e := IdmapEntry{Isuid: true, Isgid: true, Nsid: 0, Hostid: 1000000, Maprange: 1000000000}
 		idmapset.Idmap = Extend(idmapset.Idmap, e)
+		return idmapset, nil
+	}
+
+	// Look for mapped ranges
+	kernelRanges, err := kernelMap.ValidRanges()
+	if err != nil {
+		return nil, err
+	}
+
+	// Find a suitable uid range
+	for _, entry := range kernelRanges {
+		// We only care about uids right now
+		if !entry.Isuid {
+			continue
+		}
+
+		// We want a map that's separate from the system's own POSIX allocation
+		if entry.Endid < 100000 {
+			continue
+		}
+
+		// Don't use the first 65536 ids
+		if entry.Startid < 100000 {
+			entry.Startid = 100000
+		}
+
+		// Check if we have enough ids
+		if entry.Endid-entry.Startid < 65536 {
+			continue
+		}
+
+		// Add the map
+		e := IdmapEntry{Isuid: true, Isgid: false, Nsid: 0, Hostid: entry.Startid, Maprange: entry.Endid - entry.Startid + 1}
+		idmapset.Idmap = Extend(idmapset.Idmap, e)
+
+		// NOTE: Remove once LXD can deal with multiple shadow maps
+		break
+	}
+
+	// Find a suitable gid range
+	for _, entry := range kernelRanges {
+		// We only care about gids right now
+		if !entry.Isgid {
+			continue
+		}
+
+		// We want a map that's separate from the system's own POSIX allocation
+		if entry.Endid < 100000 {
+			continue
+		}
+
+		// Don't use the first 65536 ids
+		if entry.Startid < 100000 {
+			entry.Startid = 100000
+		}
+
+		// Check if we have enough ids
+		if entry.Endid-entry.Startid < 65536 {
+			continue
+		}
+
+		// Add the map
+		e := IdmapEntry{Isuid: false, Isgid: true, Nsid: 0, Hostid: entry.Startid, Maprange: entry.Endid - entry.Startid + 1}
+		idmapset.Idmap = Extend(idmapset.Idmap, e)
+
+		// NOTE: Remove once LXD can deal with multiple shadow maps
+		break
 	}
 
 	return idmapset, nil

From faaa9dfd3ca5dbbe9121c1c417a329c128053245 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 27 Feb 2017 16:47:58 -0500
Subject: [PATCH 5/5] init: Only show userns message if lacking uid/gid
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/main_init.go | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lxd/main_init.go b/lxd/main_init.go
index 7e55e4c..7dbe75c 100644
--- a/lxd/main_init.go
+++ b/lxd/main_init.go
@@ -276,7 +276,14 @@ func cmdInit() error {
 			}
 		}
 
-		if runningInUserns {
+		// Detect lack of uid/gid
+		needPrivileged := false
+		idmapset, err := shared.DefaultIdmapSet()
+		if err != nil || len(idmapset.Idmap) == 0 || idmapset.Usable() != nil {
+			needPrivileged = true
+		}
+
+		if runningInUserns && needPrivileged {
 			fmt.Printf(`
 We detected that you are running inside an unprivileged container.
 This means that unless you manually configured your host otherwise,


More information about the lxc-devel mailing list