[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