Hello community,

here is the log from the commit of package lxc for openSUSE:Factory checked in 
at 2018-09-11 17:18:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lxc (Old)
 and      /work/SRC/openSUSE:Factory/.lxc.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lxc"

Tue Sep 11 17:18:58 2018 rev:79 rq:634703 version:2.0.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/lxc/lxc.changes  2018-08-04 21:55:05.177466355 
+0200
+++ /work/SRC/openSUSE:Factory/.lxc.new/lxc.changes     2018-09-11 
17:19:14.919230654 +0200
@@ -1,0 +2,6 @@
+Mon Aug 27 06:51:25 UTC 2018 - [email protected]
+
+- 0001-Backport-autodev-fix-from-lxc-master.patch: fix unprivileged
+  lxc containers on kernel >= 4.18
+
+-------------------------------------------------------------------

New:
----
  0001-Backport-autodev-fix-from-lxc-master.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ lxc.spec ++++++
--- /var/tmp/diff_new_pack.TtveiY/_old  2018-09-11 17:19:17.975225977 +0200
+++ /var/tmp/diff_new_pack.TtveiY/_new  2018-09-11 17:19:17.979225971 +0200
@@ -34,6 +34,7 @@
 Patch0:         0001-apparmor-Allow-usr-lib-paths-for-mount-and-pivot_roo.patch
 Patch1:         0001-utils-add-LXC_PROC_PID_FD_LEN.patch
 Patch2:         0001-lxc-user-nic-verify-file-descriptor-stable-2.0.patch
+Patch3:         0001-Backport-autodev-fix-from-lxc-master.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 BuildRequires:  docbook-utils
@@ -105,6 +106,7 @@
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
 
 %build
 chmod 755 configure

++++++ 0001-Backport-autodev-fix-from-lxc-master.patch ++++++
>From 85ad111c65a5bbeb5586ad12084800c992c1dd9e Mon Sep 17 00:00:00 2001
From: Bernd Wachter <[email protected]>
Date: Mon, 27 Aug 2018 10:33:23 +0300
Subject: [PATCH] Backport autodev fix from lxc master

See description of the issue in the initial patch: 
https://github.com/lxc/lxc/commit/3e04a6083eefe0b837db6d1b826721fd985ce052
---
 src/lxc/conf.c | 92 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 63 insertions(+), 29 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 91816be..7272e25 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1146,12 +1146,20 @@ static const struct lxc_devs lxc_devs[] = {
        { "tty",     S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 5, 0 },
 };
 
+enum {
+       LXC_DEVNODE_BIND,
+       LXC_DEVNODE_MKNOD,
+       LXC_DEVNODE_PARTIAL,
+       LXC_DEVNODE_OPEN,
+};
+
 static int lxc_fill_autodev(const struct lxc_rootfs *rootfs)
 {
        int ret;
        char path[MAXPATHLEN];
        int i;
        mode_t cmask;
+       int use_mknod = LXC_DEVNODE_MKNOD;
 
        ret = snprintf(path, MAXPATHLEN, "%s/dev",
                       rootfs->path ? rootfs->mount : "");
@@ -1166,50 +1174,76 @@ static int lxc_fill_autodev(const struct lxc_rootfs 
*rootfs)
 
        cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH);
        for (i = 0; i < sizeof(lxc_devs) / sizeof(lxc_devs[0]); i++) {
-               const struct lxc_devs *d = &lxc_devs[i];
+               const struct lxc_devs *device = &lxc_devs[i];
+               char hostpath[MAXPATHLEN];
 
                ret = snprintf(path, MAXPATHLEN, "%s/dev/%s",
-                              rootfs->path ? rootfs->mount : "", d->name);
+                              rootfs->path ? rootfs->mount : "", device->name);
                if (ret < 0 || ret >= MAXPATHLEN)
                        return -1;
 
-               ret = mknod(path, d->mode, makedev(d->maj, d->min));
-               if (ret < 0) {
-                       FILE *pathfile;
-                       char hostpath[MAXPATHLEN];
+               if (use_mknod >= LXC_DEVNODE_MKNOD) {
+                       ret = mknod(path, device->mode, makedev(device->maj, 
device->min));
+                       if (ret == 0 || (ret < 0 && errno == EEXIST)) {
+                               DEBUG("Created device node \"%s\"", path);
+                       } else if (ret < 0) {
+                               if (errno != EPERM) {
+                                       SYSERROR("Failed to create device node 
\"%s\"", path);
+                                       return -1;
+                               }
+
+                               use_mknod = LXC_DEVNODE_BIND;
+                       }
 
-                       if (errno == EEXIST) {
-                               DEBUG("\"%s\" device already existed", path);
+                       /* Device nodes are fully useable. */
+                       if (use_mknod == LXC_DEVNODE_OPEN)
                                continue;
+
+                       if (use_mknod == LXC_DEVNODE_MKNOD) {
+                               /* See
+                                * - 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55956b59df336f6738da916dbb520b6e37df9fbd
+                                * - 
https://lists.linuxfoundation.org/pipermail/containers/2018-June/039176.html
+                                */
+                               ret = open(path, O_RDONLY | O_CLOEXEC);
+                               if (ret >= 0) {
+                                       close(ret);
+                                       /* Device nodes are fully useable. */
+                                       use_mknod = LXC_DEVNODE_OPEN;
+                                       continue;
+                               }
+
+                               SYSERROR("Failed to open \"%s\" device", path);
+                               /* Device nodes are only partially useable. */
+                               use_mknod = LXC_DEVNODE_PARTIAL;
                        }
+               }
 
-                       /* Unprivileged containers cannot create devices, so
-                        * bind mount the device from the host.
+               if (use_mknod != LXC_DEVNODE_PARTIAL) {
+                       /* If we are dealing with partially functional device
+                        * nodes the prio mknod() call will have created the
+                        * device node so we can use it as a bind-mount target.
                         */
-                       ret = snprintf(hostpath, MAXPATHLEN, "/dev/%s", 
d->name);
-                       if (ret < 0 || ret >= MAXPATHLEN)
-                               return -1;
-
-                       pathfile = fopen(path, "wb");
-                       if (!pathfile) {
+                       ret = mknod(path, S_IFREG | 0000, 0);
+                       if (ret < 0 && errno != EEXIST) {
                                SYSERROR("Failed to create file \"%s\"", path);
                                return -1;
                        }
-                       fclose(pathfile);
+               }
 
-                       ret = safe_mount(hostpath, path, 0, MS_BIND, NULL,
-                                        rootfs->path ? rootfs->mount : NULL);
-                       if (ret < 0) {
-                               SYSERROR("Failed to bind mount \"%s\" from "
-                                        "host into container",
-                                        d->name);
-                               return -1;
-                       }
-                       DEBUG("Bind mounted \"%s\" onto \"%s\"", hostpath,
-                             path);
-               } else {
-                       DEBUG("Created device node \"%s\"", path);
+               /* Fallback to bind-mounting the device from the host. */
+               ret = snprintf(hostpath, MAXPATHLEN, "/dev/%s", device->name);
+               if (ret < 0 || ret >= MAXPATHLEN)
+                       return -1;
+
+               ret = safe_mount(hostpath, path, 0, MS_BIND, NULL,
+                                rootfs->path ? rootfs->mount : NULL);
+               if (ret < 0) {
+                       SYSERROR("Failed to bind mount host device node \"%s\" "
+                                "onto \"%s\"", hostpath, path);
+                       return -1;
                }
+               DEBUG("Bind mounted host device node \"%s\" onto \"%s\"",
+                     hostpath, path);
        }
        umask(cmask);
 
-- 
2.18.0



Reply via email to