diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2014-01-30 17:45:08 +0000 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2014-02-18 16:34:07 +0000 |
commit | 72e379ed93b4707e26bbc5e3457a85833f50eb1a (patch) | |
tree | cec3800ff06e54de85c12d012ebb23e0104e5035 | |
parent | fcf05c194cb1cca6b5c703073b97ed1408a2c546 (diff) | |
download | libvirt-72e379ed93b4707e26bbc5e3457a85833f50eb1a.tar.gz |
CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC block hostdev hotplug
Rewrite lxcDomainAttachDeviceHostdevStorageLive function
to use the virProcessRunInMountNamespace helper. This avoids
risk of a malicious guest replacing /dev with a absolute
symlink, tricking the driver into changing the host OS
filesystem.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 1754c7f0ab1407dcf7c89636a35711dd9b1febe1)
-rw-r--r-- | src/lxc/lxc_driver.c | 66 |
1 files changed, 18 insertions, 48 deletions
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index f9b7ab72d6..552d2cb45c 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3453,11 +3453,7 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = dev->data.hostdev; int ret = -1; - char *dst = NULL; - char *vroot = NULL; struct stat sb; - bool created = false; - mode_t mode = 0; if (!def->source.caps.u.storage.block) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -3485,51 +3481,29 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, goto cleanup; } - if (virAsprintf(&vroot, "/proc/%llu/root", - (unsigned long long)priv->initpid) < 0) - goto cleanup; - - if (virAsprintf(&dst, "%s/%s", - vroot, - def->source.caps.u.storage.block) < 0) - goto cleanup; - if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) goto cleanup; - if (lxcContainerSetupHostdevCapsMakePath(dst) < 0) { - virReportSystemError(errno, - _("Unable to create directory for device %s"), - dst); - goto cleanup; - } - - mode = 0700 | S_IFBLK; - - VIR_DEBUG("Creating dev %s (%d,%d)", - def->source.caps.u.storage.block, - major(sb.st_rdev), minor(sb.st_rdev)); - if (mknod(dst, mode, sb.st_rdev) < 0) { - virReportSystemError(errno, - _("Unable to create device %s"), - dst); - goto cleanup; - } - created = true; - - if (lxcContainerChown(vm->def, dst) < 0) - goto cleanup; - - if (virSecurityManagerSetHostdevLabel(driver->securityManager, - vm->def, def, vroot) < 0) + if (virCgroupAllowDevice(priv->cgroup, + 'b', + major(sb.st_rdev), + minor(sb.st_rdev), + VIR_CGROUP_DEVICE_RWM) < 0) goto cleanup; - if (virCgroupAllowDevicePath(priv->cgroup, def->source.caps.u.storage.block, - VIR_CGROUP_DEVICE_RW | - VIR_CGROUP_DEVICE_MKNOD) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot allow device %s for domain %s"), - def->source.caps.u.storage.block, vm->def->name); + if (lxcDomainAttachDeviceMknod(driver, + 0700 | S_IFBLK, + sb.st_rdev, + vm, + dev, + def->source.caps.u.storage.block) < 0) { + if (virCgroupDenyDevice(priv->cgroup, + 'b', + major(sb.st_rdev), + minor(sb.st_rdev), + VIR_CGROUP_DEVICE_RWM) < 0) + VIR_WARN("cannot deny device %s for domain %s", + def->source.caps.u.storage.block, vm->def->name); goto cleanup; } @@ -3539,10 +3513,6 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, cleanup: virDomainAuditHostdev(vm, def, "attach", ret == 0); - if (dst && created && ret < 0) - unlink(dst); - VIR_FREE(dst); - VIR_FREE(vroot); return ret; } |