[lxc-devel] [lxd/master] Fix setxattr handling

stgraber on Github lxc-bot at linuxcontainers.org
Sun Jul 21 19:08:53 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 975 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190721/fd32b9e6/attachment.bin>
-------------- next part --------------
From 6e1511c78525d258a09c8e66e30d61d1f93fef0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:05:34 -0400
Subject: [PATCH 1/6] lxd/seccomp: Use LXD uidmap 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>
---
 lxd/container_lxc.go    | 10 +++++--
 lxd/main_forksyscall.go | 60 -----------------------------------------
 lxd/seccomp.go          | 11 +++++---
 3 files changed, 15 insertions(+), 66 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 98f28fd511..18169763ec 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -7608,8 +7608,14 @@ func (c *containerLXC) InsertSeccompUnixDevice(prefix string, m types.Device, pi
 		return err
 	}
 
-	m["uid"] = fmt.Sprintf("%d", GetNSUid(uint(uid), pid))
-	m["gid"] = fmt.Sprintf("%d", GetNSGid(uint(gid), pid))
+	idmapset, err := c.CurrentIdmap()
+	if err != nil {
+		return err
+	}
+
+	nsuid, nsgid := idmapset.ShiftFromNs(uid, gid)
+	m["uid"] = fmt.Sprintf("%d", nsuid)
+	m["gid"] = fmt.Sprintf("%d", nsgid)
 
 	if !path.IsAbs(m["path"]) {
 		cwdLink := fmt.Sprintf("/proc/%d/cwd", pid)
diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index 1b7f2e35ac..edb8cb7cb5 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -31,58 +31,6 @@ import (
 extern char* advance_arg(bool required);
 extern int dosetns(int pid, char *nstype);
 
-static uid_t get_ns_uid(uid_t uid, pid_t pid)
-{
-        __do_free char *line = NULL;
-        __do_fclose FILE *f = NULL;
-        size_t sz = 0;
-	char path[256];
-        uid_t nsid, hostid, range;
-
-	snprintf(path, sizeof(path), "/proc/%d/uid_map", pid);
-	f = fopen(path, "re");
-	if (!f)
-		return -1;
-
-        while (getline(&line, &sz, f) != -1) {
-                if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3)
-                        continue;
-
-                if (nsid <= uid && nsid + range > uid) {
-                        nsid += uid - hostid;
-			return nsid;
-                }
-        }
-
-        return -1;
-}
-
-static gid_t get_ns_gid(uid_t gid, pid_t pid)
-{
-        __do_free char *line = NULL;
-        __do_fclose FILE *f = NULL;
-        size_t sz = 0;
-	char path[256];
-        uid_t nsid, hostid, range;
-
-	snprintf(path, sizeof(path), "/proc/%d/gid_map", pid);
-	f = fopen(path, "re");
-	if (!f)
-		return -1;
-
-        while (getline(&line, &sz, f) != -1) {
-                if (sscanf(line, "%u %u %u", &nsid, &hostid, &range) != 3)
-                        continue;
-
-                if (nsid <= gid && nsid + range > gid) {
-                        nsid += gid - hostid;
-			return nsid;
-                }
-        }
-
-        return -1;
-}
-
 static inline bool same_fsinfo(struct stat *s1, struct stat *s2,
 			       struct statfs *sfs1, struct statfs *sfs2)
 {
@@ -411,14 +359,6 @@ type cmdForksyscall struct {
 	global *cmdGlobal
 }
 
-func GetNSUid(uid uint, pid int) int {
-	return int(C.get_ns_uid(C.uid_t(uid), C.pid_t(pid)))
-}
-
-func GetNSGid(gid uint, pid int) int {
-	return int(C.get_ns_gid(C.gid_t(gid), C.pid_t(pid)))
-}
-
 func (c *cmdForksyscall) Command() *cobra.Command {
 	// Main subcommand
 	cmd := &cobra.Command{}
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 0f9e1e0ca9..8dbc8b2415 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -1066,10 +1066,13 @@ func (s *SeccompServer) HandleSetxattrSyscall(c container, siov *SeccompIovec) i
 		return int(-C.EPERM)
 	}
 
-	args.nsuid = GetNSUid(uint(uid), args.pid)
-	args.nsgid = GetNSGid(uint(gid), args.pid)
-	args.nsfsuid = GetNSUid(uint(fsuid), args.pid)
-	args.nsfsgid = GetNSGid(uint(fsgid), args.pid)
+	idmapset, err := c.CurrentIdmap()
+	if err != nil {
+		return int(-C.EINVAL)
+	}
+
+	args.nsuid, args.nsgid = idmapset.ShiftFromNs(uid, gid)
+	args.nsfsuid, args.nsfsgid = idmapset.ShiftFromNs(fsuid, fsgid)
 
 	// const char *path
 	cBuf := [unix.PathMax]C.char{}

From 4039f475305c8f66a5881a159fa28ea563eead18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:05:51 -0400
Subject: [PATCH 2/6] lxd/seccomp: Use int64 for 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/seccomp.go | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 8dbc8b2415..0dbcbb21be 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -788,7 +788,7 @@ func NewSeccompServer(d *Daemon, path string) (*SeccompServer, error) {
 	return &s, nil
 }
 
-func taskIds(pid int) (error, int32, int32, int32, int32) {
+func taskIds(pid int) (error, int64, int64, int64, int64) {
 	status, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/status", pid))
 	if err != nil {
 		return err, -1, -1, -1, -1
@@ -796,10 +796,10 @@ func taskIds(pid int) (error, int32, int32, int32, int32) {
 
 	reUid := regexp.MustCompile("Uid:\\s*([0-9]*)\\s*([0-9]*)\\s*([0-9]*)\\s*([0-9]*)")
 	reGid := regexp.MustCompile("Gid:\\s*([0-9]*)\\s*([0-9]*)\\s*([0-9]*)\\s*([0-9]*)")
-	var gid int32 = -1
-	var uid int32 = -1
-	var fsgid int32 = -1
-	var fsuid int32 = -1
+	var gid int64 = -1
+	var uid int64 = -1
+	var fsgid int64 = -1
+	var fsuid int64 = -1
 	uidFound := false
 	gidFound := false
 	for _, line := range strings.Split(string(status), "\n") {
@@ -811,23 +811,23 @@ func taskIds(pid int) (error, int32, int32, int32, int32) {
 			m := reUid.FindStringSubmatch(line)
 			if m != nil && len(m) > 2 {
 				// effective uid
-				result, err := strconv.Atoi(m[2])
+				result, err := strconv.ParseInt(m[2], 10, 64)
 				if err != nil {
 					return err, -1, -1, -1, -1
 				}
 
-				uid = int32(result)
+				uid = result
 				uidFound = true
 			}
 
 			if m != nil && len(m) > 4 {
 				// fsuid
-				result, err := strconv.Atoi(m[4])
+				result, err := strconv.ParseInt(m[4], 10, 64)
 				if err != nil {
 					return err, -1, -1, -1, -1
 				}
 
-				fsuid = int32(result)
+				fsuid = result
 			}
 
 			continue
@@ -837,23 +837,23 @@ func taskIds(pid int) (error, int32, int32, int32, int32) {
 			m := reGid.FindStringSubmatch(line)
 			if m != nil && len(m) > 2 {
 				// effective gid
-				result, err := strconv.Atoi(m[2])
+				result, err := strconv.ParseInt(m[2], 10, 64)
 				if err != nil {
 					return err, -1, -1, -1, -1
 				}
 
-				gid = int32(result)
+				gid = result
 				gidFound = true
 			}
 
 			if m != nil && len(m) > 4 {
 				// fsgid
-				result, err := strconv.Atoi(m[4])
+				result, err := strconv.ParseInt(m[4], 10, 64)
 				if err != nil {
 					return err, -1, -1, -1, -1
 				}
 
-				fsgid = int32(result)
+				fsgid = result
 			}
 
 			continue
@@ -1036,10 +1036,10 @@ func (s *SeccompServer) HandleMknodatSyscall(c container, siov *SeccompIovec) in
 }
 
 type SetxattrArgs struct {
-	nsuid   int
-	nsgid   int
-	nsfsuid int
-	nsfsgid int
+	nsuid   int64
+	nsgid   int64
+	nsfsuid int64
+	nsfsgid int64
 	size    int
 	pid     int
 	path    string

From bdcae661a9bd295da4148821e4435aabf1d0d604 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:06:20 -0400
Subject: [PATCH 3/6] lxd/seccomp: Don't hardcode ns type
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_forksyscall.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index edb8cb7cb5..020484431a 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -214,7 +214,7 @@ static bool setnsat(int ns_fd, const char *ns)
 	if (fd < 0)
 		return false;
 
-	return setns(fd, CLONE_NEWUSER) == 0;
+	return setns(fd, 0) == 0;
 }
 
 static bool change_creds(int ns_fd, cap_t caps, uid_t nsuid, gid_t nsgid, uid_t nsfsuid, gid_t nsfsgid)

From a494ea61cbdfaba09239dd4a532c0d3636325e3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:06:44 -0400
Subject: [PATCH 4/6] lxd/seccomp: Fix setattr of directories
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_forksyscall.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index 020484431a..b88e71e9dc 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -284,7 +284,7 @@ static void forksetxattr()
 		_exit(EXIT_FAILURE);
 	}
 
-	target_fd = open(path, O_RDWR | O_CLOEXEC);
+	target_fd = open(path, O_RDONLY | O_CLOEXEC);
 	if (target_fd < 0) {
 		fprintf(stderr, "%d", errno);
 		_exit(EXIT_FAILURE);

From 516bbe9c3d5ccc575fa49f4f7b2b3b90d3c86f69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:06:54 -0400
Subject: [PATCH 5/6] lxd/seccomp: Always use setfattr
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_forksyscall.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/main_forksyscall.go b/lxd/main_forksyscall.go
index b88e71e9dc..836d7cb0b9 100644
--- a/lxd/main_forksyscall.go
+++ b/lxd/main_forksyscall.go
@@ -309,7 +309,7 @@ static void forksetxattr()
 	}
 
 	if (whiteout == 1) {
-		if (setxattr(path, "trusted.overlay.opaque", "y", 1, flags)) {
+		if (fsetxattr(target_fd, "trusted.overlay.opaque", "y", 1, flags)) {
 			fprintf(stderr, "%d", errno);
 			_exit(EXIT_FAILURE);
 		}

From 1bcd84a4c70dc1cf5a7d199a44cb6be30846f174 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 21 Jul 2019 15:07:06 -0400
Subject: [PATCH 6/6] lxd/seccomp: Fix whiteout detection
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/seccomp.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 0dbcbb21be..fb904a0368 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -1106,7 +1106,7 @@ func (s *SeccompServer) HandleSetxattrSyscall(c container, siov *SeccompIovec) i
 	args.value = buf
 
 	whiteout := 0
-	if args.size == 1 && string(args.value) == "y" {
+	if string(args.name) == "trusted.overlay.opaque" && string(args.value) == "y" {
 		whiteout = 1
 	}
 


More information about the lxc-devel mailing list