]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
LXC: Fix virLXCControllerSetupDevPTS() wrt user namespaces
authorRichard Weinberger <richard@nod.at>
Mon, 28 Jul 2014 20:59:17 +0000 (22:59 +0200)
committerJán Tomko <jtomko@redhat.com>
Thu, 14 Aug 2014 12:32:49 +0000 (14:32 +0200)
The gid value passed to devpts has to be translated by hand as
virLXCControllerSetupDevPTS() is called before setting up the user
and group mappings.
Otherwise devpts will use an unmapped gid and openpty()
will fail within containers.
Linux kernel commit 23adbe12
("fs,userns: Change inode_capable to capable_wrt_inode_uidgid")
uncovered that issue.

Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
src/lxc/lxc_controller.c

index 2d220eb44b3edacb671d9f9ad017130d33efdf03..1861dd6fdb4800955b3921616b320f7cbd8d2913 100644 (file)
@@ -1164,6 +1164,20 @@ static int virLXCControllerMain(virLXCControllerPtr ctrl)
     return rc;
 }
 
+static unsigned int
+virLXCControllerLookupUsernsMap(virDomainIdMapEntryPtr map,
+                                int num,
+                                unsigned int src)
+{
+    size_t i;
+
+    for (i = 0; i < num; i++) {
+        if (src > map[i].start && src < map[i].start + map[i].count)
+            return map[i].target + (src - map[i].start);
+    }
+
+    return src;
+}
 
 static int
 virLXCControllerSetupUsernsMap(virDomainIdMapEntryPtr map,
@@ -1930,6 +1944,7 @@ virLXCControllerSetupDevPTS(virLXCControllerPtr ctrl)
     char *opts = NULL;
     char *devpts = NULL;
     int ret = -1;
+    gid_t ptsgid = 5;
 
     VIR_DEBUG("Setting up private /dev/pts");
 
@@ -1949,10 +1964,15 @@ virLXCControllerSetupDevPTS(virLXCControllerPtr ctrl)
         goto cleanup;
     }
 
+    if (ctrl->def->idmap.ngidmap)
+        ptsgid = virLXCControllerLookupUsernsMap(ctrl->def->idmap.gidmap,
+                                                 ctrl->def->idmap.ngidmap,
+                                                 ptsgid);
+
     /* XXX should we support gid=X for X!=5 for distros which use
      * a different gid for tty?  */
-    if (virAsprintf(&opts, "newinstance,ptmxmode=0666,mode=0620,gid=5%s",
-                    (mount_options ? mount_options : "")) < 0)
+    if (virAsprintf(&opts, "newinstance,ptmxmode=0666,mode=0620,gid=%u%s",
+                    ptsgid, (mount_options ? mount_options : "")) < 0)
         goto cleanup;
 
     VIR_DEBUG("Mount devpts on %s type=tmpfs flags=%x, opts=%s",