[libvirt] [PATCH 5/5] qemuDomainDetachDeviceUnlink: Don't unlink files we haven't created

Cedric Bosdonnat cbosdonnat at suse.com
Wed May 3 13:30:50 UTC 2017


On Fri, 2017-04-28 at 13:22 +0200, Michal Privoznik wrote:
> Even though there are several checks before calling this function
> and for some scenarios we don't call it at all (e.g. on disk hot
> unplug), it may be possible to sneak in some weird files (e.g. if
> domain would have RNG with /dev/shm/some_file as its backend). No
> matter how improbable, we shouldn't unlink it as we would be
> unlinking a file from the host which we haven't created in the
> first place.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/qemu/qemu_domain.c | 86 ++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 76 insertions(+), 10 deletions(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 60f8f01..c393d5e 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -8395,14 +8395,32 @@ qemuDomainDetachDeviceUnlinkHelper(pid_t pid ATTRIBUTE_UNUSED,
>  static int
>  qemuDomainDetachDeviceUnlink(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
>                               virDomainObjPtr vm,
> -                             const char *file)
> +                             const char *file,
> +                             char * const *devMountsPath,
> +                             size_t ndevMountsPath)
>  {
> -    if (virProcessRunInMountNamespace(vm->pid,
> -                                      qemuDomainDetachDeviceUnlinkHelper,
> -                                      (void *)file) < 0)
> -        return -1;
> +    int ret = -1;
> +    size_t i;
>  
> -    return 0;
> +    if (STRPREFIX(file, DEVPREFIX)) {
> +        for (i = 0; i < ndevMountsPath; i++) {
> +            if (STREQ(devMountsPath[i], "/dev"))
> +                continue;
> +            if (STRPREFIX(file, devMountsPath[i]))
> +                break;
> +        }
> +
> +        if (i == ndevMountsPath) {
> +            if (virProcessRunInMountNamespace(vm->pid,
> +                                              qemuDomainDetachDeviceUnlinkHelper,
> +                                              (void *)file) < 0)
> +                goto cleanup;
> +        }
> +    }
> +
> +    ret = 0;
> + cleanup:
> +    return ret;
>  }
>  
>  
> @@ -8521,6 +8539,9 @@ qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver,
>                                     virDomainObjPtr vm,
>                                     virDomainHostdevDefPtr hostdev)
>  {
> +    virQEMUDriverConfigPtr cfg = NULL;
> +    char **devMountsPath = NULL;
> +    size_t ndevMountsPath = 0;
>      int ret = -1;
>      char **path = NULL;
>      size_t i, npaths = 0;
> @@ -8532,8 +8553,15 @@ qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver,
>                                   &npaths, &path, NULL) < 0)
>          goto cleanup;
>  
> +    cfg = virQEMUDriverGetConfig(driver);
> +    if (qemuDomainGetPreservedMounts(cfg, vm,
> +                                     &devMountsPath, NULL,
> +                                     &ndevMountsPath) < 0)
> +        goto cleanup;
> +
>      for (i = 0; i < npaths; i++) {
> -        if (qemuDomainDetachDeviceUnlink(driver, vm, path[i]) < 0)
> +        if (qemuDomainDetachDeviceUnlink(driver, vm, path[i],
> +                                         devMountsPath, ndevMountsPath) < 0)
>              goto cleanup;
>      }
>  
> @@ -8542,6 +8570,8 @@ qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver,
>      for (i = 0; i < npaths; i++)
>          VIR_FREE(path[i]);
>      VIR_FREE(path);
> +    virStringListFreeCount(devMountsPath, ndevMountsPath);
> +    virObjectUnref(cfg);
>      return ret;
>  }
>  
> @@ -8584,6 +8614,9 @@ qemuDomainNamespaceTeardownMemory(virQEMUDriverPtr driver,
>                                    virDomainObjPtr vm,
>                                    virDomainMemoryDefPtr mem)
>  {
> +    virQEMUDriverConfigPtr cfg = NULL;
> +    char **devMountsPath = NULL;
> +    size_t ndevMountsPath = 0;
>      int ret = -1;
>  
>      if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM)
> @@ -8592,10 +8625,19 @@ qemuDomainNamespaceTeardownMemory(virQEMUDriverPtr driver,
>      if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
>          return 0;
>  
> -    if (qemuDomainDetachDeviceUnlink(driver, vm, mem->nvdimmPath) < 0)
> +    cfg = virQEMUDriverGetConfig(driver);
> +    if (qemuDomainGetPreservedMounts(cfg, vm,
> +                                     &devMountsPath, NULL,
> +                                     &ndevMountsPath) < 0)
> +        goto cleanup;
> +
> +    if (qemuDomainDetachDeviceUnlink(driver, vm, mem->nvdimmPath,
> +                                     devMountsPath, ndevMountsPath) < 0)
>          goto cleanup;
>      ret = 0;
>   cleanup:
> +    virStringListFreeCount(devMountsPath, ndevMountsPath);
> +    virObjectUnref(cfg);
>      return ret;
>  }
>  
> @@ -8643,6 +8685,9 @@ qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
>                                     virDomainObjPtr vm,
>                                     virDomainChrDefPtr chr)
>  {
> +    virQEMUDriverConfigPtr cfg = NULL;
> +    char **devMountsPath = NULL;
> +    size_t ndevMountsPath = 0;
>      int ret = -1;
>      const char *path = NULL;
>  
> @@ -8654,11 +8699,20 @@ qemuDomainNamespaceTeardownChardev(virQEMUDriverPtr driver,
>  
>      path = chr->source->data.file.path;
>  
> -    if (qemuDomainDetachDeviceUnlink(driver, vm, path) < 0)
> +    cfg = virQEMUDriverGetConfig(driver);
> +    if (qemuDomainGetPreservedMounts(cfg, vm,
> +                                     &devMountsPath, NULL,
> +                                     &ndevMountsPath) < 0)
> +        goto cleanup;
> +
> +    if (qemuDomainDetachDeviceUnlink(driver, vm, path,
> +                                     devMountsPath, ndevMountsPath) < 0)
>          goto cleanup;
>  
>      ret = 0;
>   cleanup:
> +    virStringListFreeCount(devMountsPath, ndevMountsPath);
> +    virObjectUnref(cfg);
>      return ret;
>  }
>  
> @@ -8712,6 +8766,9 @@ qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
>                                 virDomainObjPtr vm,
>                                 virDomainRNGDefPtr rng)
>  {
> +    virQEMUDriverConfigPtr cfg = NULL;
> +    char **devMountsPath = NULL;
> +    size_t ndevMountsPath = 0;
>      int ret = -1;
>      const char *path = NULL;
>  
> @@ -8729,11 +8786,20 @@ qemuDomainNamespaceTeardownRNG(virQEMUDriverPtr driver,
>          goto cleanup;
>      }
>  
> -    if (qemuDomainDetachDeviceUnlink(driver, vm, path) < 0)
> +    cfg = virQEMUDriverGetConfig(driver);
> +    if (qemuDomainGetPreservedMounts(cfg, vm,
> +                                     &devMountsPath, NULL,
> +                                     &ndevMountsPath) < 0)
> +        goto cleanup;
> +
> +    if (qemuDomainDetachDeviceUnlink(driver, vm, path,
> +                                     devMountsPath, ndevMountsPath) < 0)
>          goto cleanup;
>  
>      ret = 0;
>   cleanup:
> +    virStringListFreeCount(devMountsPath, ndevMountsPath);
> +    virObjectUnref(cfg);
>      return ret;
>  }
>  
ACK

--
Cedric




More information about the libvir-list mailing list