[libvirt] [PATCH v3]LXC: Helper function for checking permission of dir when userns enabled

Chen Hanxiao chenhanxiao at cn.fujitsu.com
Wed Oct 9 10:02:34 UTC 2013


ping?

> -----Original Message-----
> From: Chen Hanxiao [mailto:chenhanxiao at cn.fujitsu.com]
> Sent: Tuesday, September 10, 2013 4:18 PM
> To: libvir-list at redhat.com
> Cc: chenhanxiao at cn.fujitsu.com
> Subject: [libvirt][PATCH v3]LXC: Helper function for checking permission of dir
> when userns enabled
> 
> From: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
> 
> If we enable userns, the process with uid/gid in idmap
> should have enough permission to access dir we provided
> for containers.
> Currently, the debug log is very implicit
> or misleading sometimes.
> This patch will help clarify this for us
> when using debug log or virsh.
> 
> v2: syntax-check clean
> 
> v3: reliable method for checking permission of dir
> 
> Signed-off-by: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
> ---
>  src/lxc/lxc_container.c | 88
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 88 insertions(+)
> 
> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> index 8abaea0..9a05e30 100644
> --- a/src/lxc/lxc_container.c
> +++ b/src/lxc/lxc_container.c
> @@ -110,6 +110,13 @@ struct __lxc_child_argv {
>      int handshakefd;
>  };
> 
> +typedef struct __lxc_userns_DirPermCheck_argv
> lxc_userns_DirPermCheck_argv_t;
> +struct __lxc_userns_DirPermCheck_argv {
> +    uid_t uid;
> +    gid_t gid;
> +    virDomainDefPtr vmDef;
> +};
> +
>  static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
>                                      const char *srcprefix);
> 
> @@ -1829,6 +1836,84 @@ lxcNeedNetworkNamespace(virDomainDefPtr def)
>      return false;
>  }
> 
> +static
> +int lxcContainerCheckDirPermissionChild(void *argv)
> +{
> +    size_t i;
> +    lxc_userns_DirPermCheck_argv_t *args = argv;
> +    uid_t uid = args->uid;
> +    uid_t gid = args->gid;
> +    virDomainDefPtr vmDef = args->vmDef;
> +    char *path;
> +
> +    if (virSetUIDGID(uid, gid, NULL, 0) < 0) {
> +        virReportSystemError(errno, "%s",
> +                              _("setuid or setgid failed"));
> +        _exit(-1);
> +    }
> +
> +    for (i = 0; i < vmDef->nfss; i++) {
> +        path = vmDef->fss[i]->src;
> +        if (access(path, R_OK) || access(path, W_OK) ||
> virFileIsExecutable(path)) {
> +            VIR_DEBUG("Src dir '%s' does not belong to uid/gid: %d/%d",
> +                      vmDef->fss[i]->src, uid, gid);
> +            _exit(-1);
> +        }
> +    }
> +
> +    _exit(0);
> +}
> +
> +/*
> + * Helper function for helping check
> + * whether we have enough privilege
> + * to operate the source dir when userns enabled
> + * @vmDef: pointer to vm definition structure
> + * Returns 0 on success or -1 in case of error
> + */
> +static int
> +lxcContainerCheckDirPermission(virDomainDefPtr vmDef)
> +{
> +    uid_t uid;
> +    gid_t gid;
> +    int cpid = 0;
> +    int status;
> +    char *childStack;
> +    char *stack;
> +    int flags =  SIGCHLD;
> +
> +    uid = vmDef->idmap.uidmap[0].target;
> +    gid = vmDef->idmap.gidmap[0].target;
> +
> +    lxc_userns_DirPermCheck_argv_t args = {
> +        .uid = uid,
> +        .gid = gid,
> +        .vmDef = vmDef
> +    };
> +
> +    if (VIR_ALLOC_N(stack, getpagesize() * 4) < 0)
> +        return -1;
> +
> +    childStack = stack + (getpagesize() * 4);
> +    cpid = clone(lxcContainerCheckDirPermissionChild, childStack, flags,
> &args);
> +    VIR_FREE(stack);
> +    if (cpid < 0) {
> +        virReportSystemError(errno, "%s",
> +                             _("Unable to clone to check permission of
> directory"));
> +        return -1;
> +    } else if (virProcessWait(cpid, &status) < 0) {
> +        return -1;
> +    }
> +
> +    if (WEXITSTATUS(status) != 0) {
> +        virReportSystemError(errno, "%s",
> +                             _("Check the permission of source dir
> provided for container"));
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  /**
>   * lxcContainerStart:
>   * @def: pointer to virtual machine structure
> @@ -1880,6 +1965,9 @@ int lxcContainerStart(virDomainDefPtr def,
>          if (userns_supported()) {
>              VIR_DEBUG("Enable user namespace");
>              cflags |= CLONE_NEWUSER;
> +            if (lxcContainerCheckDirPermission(def) < 0) {
> +                return -1;
> +            }
>          } else {
>              virReportSystemError(VIR_ERR_CONFIG_UNSUPPORTED,
> "%s",
>                                   _("Kernel doesn't support user
> namespace"));
> --
> 1.8.2.1







More information about the libvir-list mailing list