[libvirt] [PATCH] screenshot: don't unlink bogus file
Laine Stump
laine at laine.org
Tue Aug 2 19:03:03 UTC 2011
On 08/02/2011 01:11 PM, Eric Blake wrote:
> The previous qemu patch could end up calling unlink(tmp) before
> tmp was the name of a valid file (unlinking a fileXXXXXX template
> instead), or calling unlink(tmp) twice on success (once here,
> and once at the end of the stream). Meanwhile, vbox also suffered
> from the same leaked tmp file bug.
>
ACK.
> * src/qemu/qemu_driver.c (qemuDomainScreenshot): Don't unlink on
> success, or on invalid name.
> * src/vbox/vbox_tmpl.c (vboxDomainScreenshot): Don't leak temp file.
> ---
>
>> Meanwhile, I wonder if we have a bigger bug - that is, should
>> virFDStreamOpenInternal guarantee that the file is deleted when
>> requested, even on failure paths, so that callers need not do the
>> unlink()? That is, on the success path, we end up unlink()ing the
>> same name twice, which is racy if the name is predictable (in the case
>> of qemuDomainScreenshot, the name is temporary and supposedly safe).
> I audited all callers, and there were only two that passed delete=true.
> Of those two, I found another bug (calling unlink() too soon).
>
> Additionally, remember that the reason we passed delete=true in the
> first place was due to libvirt_iohelper doing the unlink in a child
> process; where a race condition required that we not do the unlink in
> the parent. But now that libvirt_iohelper receives its fd by
> inheritance, I think we can revert the delete parameter in the
> first place. But that's invasive enough to delay to post-release.
>
> Meanwhile, I still think this is worth applying pre-release.
>
> src/qemu/qemu_driver.c | 8 ++++----
> src/vbox/vbox_tmpl.c | 5 +++++
> 2 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 5e2c903..0297159 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -2912,18 +2912,21 @@ qemuDomainScreenshot(virDomainPtr dom,
> qemuDomainObjEnterMonitor(driver, vm);
> if (qemuMonitorScreendump(priv->mon, tmp)< 0) {
> qemuDomainObjExitMonitor(driver, vm);
> + unlink(tmp);
> goto endjob;
> }
> qemuDomainObjExitMonitor(driver, vm);
>
> if (VIR_CLOSE(tmp_fd)< 0) {
> virReportSystemError(errno, _("unable to close %s"), tmp);
> + unlink(tmp);
> goto endjob;
> }
>
> if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY, true)< 0) {
> qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
> _("unable to open stream"));
> + unlink(tmp);
> goto endjob;
> }
>
> @@ -2931,10 +2934,7 @@ qemuDomainScreenshot(virDomainPtr dom,
>
> endjob:
> VIR_FORCE_CLOSE(tmp_fd);
> - if (tmp) {
> - unlink(tmp);
> - VIR_FREE(tmp);
> - }
> + VIR_FREE(tmp);
>
> if (qemuDomainObjEndJob(driver, vm) == 0)
> vm = NULL;
> diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
> index a7d354e..66a0fe9 100644
> --- a/src/vbox/vbox_tmpl.c
> +++ b/src/vbox/vbox_tmpl.c
> @@ -8713,6 +8713,7 @@ vboxDomainScreenshot(virDomainPtr dom,
> if (NS_FAILED(rc) || !width || !height) {
> vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> _("unable to get screen resolution"));
> + unlink(tmp);
> goto endjob;
> }
>
> @@ -8723,6 +8724,7 @@ vboxDomainScreenshot(virDomainPtr dom,
> if (NS_FAILED(rc)) {
> vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> _("failed to take screenshot"));
> + unlink(tmp);
> goto endjob;
> }
>
> @@ -8730,17 +8732,20 @@ vboxDomainScreenshot(virDomainPtr dom,
> screenDataSize)< 0) {
> virReportSystemError(errno, _("unable to write data "
> "to '%s'"), tmp);
> + unlink(tmp);
> goto endjob;
> }
>
> if (VIR_CLOSE(tmp_fd)< 0) {
> virReportSystemError(errno, _("unable to close %s"), tmp);
> + unlink(tmp);
> goto endjob;
> }
>
> if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY, true)< 0) {
> vboxError(VIR_ERR_OPERATION_FAILED, "%s",
> _("unable to open stream"));
> + unlink(tmp);
> goto endjob;
> }
>
More information about the libvir-list
mailing list