The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/5939

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 45d9266290459f78c837407d19f0f2f57bc6aa9c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Thu, 11 Jul 2019 16:36:30 +0200
Subject: [PATCH 1/2] forkmknod: check for MS_NODEV

Note that we use MS_NODEV even though statfs says ST_NODEV.
MS_NODEV and ST_NODEV are equivalent. Note, that this is __not__ true
for all all MS_* and ST_* flags. So don't blindly copy what I'm doing
here.

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 lxd/main_forkmknod.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/main_forkmknod.go b/lxd/main_forkmknod.go
index 6402580989..4d23cd3453 100644
--- a/lxd/main_forkmknod.go
+++ b/lxd/main_forkmknod.go
@@ -197,7 +197,7 @@ void forkmknod()
                _exit(EXIT_FAILURE);
        }
 
-       if (!same_fsinfo(&s1, &s2, &sfs1, &sfs2)) {
+       if (!same_fsinfo(&s1, &s2, &sfs1, &sfs2) || !(sfs2.f_flags & MS_NODEV)) 
{
                fprintf(stderr, "%d", ENOMEDIUM);
                _exit(EXIT_FAILURE);
        }

From f06eede3f7d5ba55636a7ee892fa3a39a15b61a5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Thu, 11 Jul 2019 16:42:46 +0200
Subject: [PATCH 2/2] seccomp: check permissions before handling mknod via
 device injection

Note that this is inherently racy until we switch to pidfd_open()...

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 lxd/main_forkmknod.go |  5 +++++
 lxd/seccomp.go        | 12 +++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/lxd/main_forkmknod.go b/lxd/main_forkmknod.go
index 4d23cd3453..226309ba5e 100644
--- a/lxd/main_forkmknod.go
+++ b/lxd/main_forkmknod.go
@@ -114,6 +114,7 @@ void forkmknod()
        struct stat s1, s2;
        struct statfs sfs1, sfs2;
        cap_t caps;
+       int chk_perm_only;
 
        // Get the subcommand
        cur = advance_arg(false);
@@ -135,6 +136,7 @@ void forkmknod()
        target_host = advance_arg(true);
        uid = atoi(advance_arg(true));
        gid = atoi(advance_arg(true));
+       chk_perm_only = atoi(advance_arg(true));
 
        snprintf(cwd, sizeof(cwd), "/proc/%d/cwd", pid);
        target_fd = open(cwd, O_PATH | O_RDONLY | O_CLOEXEC);
@@ -202,6 +204,9 @@ void forkmknod()
                _exit(EXIT_FAILURE);
        }
 
+       if (chk_perm_only)
+               _exit(EXIT_SUCCESS);
+
        // basename() can modify its argument so accessing target_host is
        // invalid from now on.
        ret = mknodat(target_fd, target, mode, dev);
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 6e5a497e17..2c9e8e5132 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -771,7 +771,7 @@ func taskUidGid(pid int) (error, int32, int32) {
        return nil, uid, gid
 }
 
-func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int) 
(error, int) {
+func (s *SeccompServer) doMknod(c container, dev types.Device, requestPID int, 
permissionsOnly bool) (error, int) {
        goErrno := int(-C.EPERM)
 
        cwdLink := fmt.Sprintf("/proc/%d/cwd", requestPID)
@@ -796,7 +796,8 @@ func (s *SeccompServer) doMknod(c container, dev 
types.Device, requestPID int) (
        errnoMsg, err := shared.RunCommand(util.GetExecPath(),
                "forkmknod", dev["pid"], dev["path"],
                dev["mode_t"], dev["dev_t"], dev["hostpath"],
-               fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid))
+               fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid),
+               fmt.Sprintf("%d", permissionsOnly))
        if err != nil {
                tmp, err2 := strconv.Atoi(errnoMsg)
                if err2 == nil {
@@ -865,9 +866,14 @@ func (s *SeccompServer) Handler(c net.Conn, clientFd int, 
ucred *ucred,
                        }
 
                        if s.d.os.Shiftfs && !c.IsPrivileged() && diskIdmap == 
nil {
+                               err, _ = s.doMknod(c, dev, int(cPid), true)
+                               if err != nil {
+                                       goErrno = int(-C.EPERM)
+                                       goto send_response
+                               }
                                err = 
c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, 
int(cPid))
                        } else {
-                               err, goErrno = s.doMknod(c, dev, int(cPid))
+                               err, goErrno = s.doMknod(c, dev, int(cPid), 
false)
                                if err != nil && (goErrno == int(-C.ENOMEDIUM)) 
&& c != nil {
                                        err = 
c.InsertSeccompUnixDevice(fmt.Sprintf("forkmknod.unix.%d", int(cPid)), dev, 
int(cPid))
                                        if err != nil {
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to