[lxc-devel] [lxc/master] autodev: adapt to changes in Linux 4.18
brauner on Github
lxc-bot at linuxcontainers.org
Fri Jun 29 12:19:48 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1465 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180629/8fcd53be/attachment.bin>
-------------- next part --------------
From cd541e9415fcb2bf5f05111d24aa9e1573327f8f Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 29 Jun 2018 13:58:52 +0200
Subject: [PATCH] autodev: adapt to changes in Linux 4.18
Starting with commit
55956b59df33 ("vfs: Allow userns root to call mknod on owned filesystems.")
Linux will allow mknod() in user namespaces for userns root if CAP_MKNOD is
available.
However, these device nodes are useless since
static struct super_block *alloc_super(struct file_system_type *type, int flags,
struct user_namespace *user_ns)
{
/* <snip> */
if (s->s_user_ns != &init_user_ns)
s->s_iflags |= SB_I_NODEV;
/* <snip> */
}
will set the SB_I_NODEV flag on the filesystem. When a device node created in
non-init userns is open()ed the call chain will hit:
bool may_open_dev(const struct path *path)
{
return !(path->mnt->mnt_flags & MNT_NODEV) &&
!(path->mnt->mnt_sb->s_iflags & SB_I_NODEV);
}
which will cause an EPERM because the device node is located on an fs
owned by non-init-userns and thus doesn't grant access to device nodes due to
SB_I_NODEV.
The solution is straightforward. Unless you're real root you should bind-mount
device nodes.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/conf.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index ee0e7bddd..cc37b8637 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1251,7 +1251,7 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs)
int i, ret;
char path[MAXPATHLEN];
mode_t cmask;
- bool can_mknod = true;
+ int can_mknod = 1;
ret = snprintf(path, MAXPATHLEN, "%s/dev",
rootfs->path ? rootfs->mount : "");
@@ -1274,7 +1274,11 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs)
if (ret < 0 || ret >= MAXPATHLEN)
return -1;
- if (can_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
+ */
+ if (can_mknod == 2 || (can_mknod == 1 && !am_host_unpriv())) {
ret = mknod(path, device->mode, makedev(device->maj, device->min));
if (ret == 0 || (ret < 0 && errno == EEXIST)) {
DEBUG("Created device node \"%s\"", path);
@@ -1289,7 +1293,9 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs)
/* This can e.g. happen when the container is
* unprivileged or CAP_MKNOD has been dropped.
*/
- can_mknod = false;
+ can_mknod = 2;
+ } else {
+ can_mknod = 0;
}
ret = mknod(path, S_IFREG, 0);
More information about the lxc-devel
mailing list