From 1768bf63edf96c66aba25ddf85b2bf3a6b842630 Mon Sep 17 00:00:00 2001 From: Alex Jia Date: Thu, 28 Jul 2011 10:42:51 +0800 Subject: [PATCH] virsh: fix memory leak in cmdVolPath code * tools/virsh.c: avoid memory leak in cmdVolPath. * src/libvirt.c: Add doc for virStorageVolGetPath to tell one must free() the returned path after use. * how to reproduce? % dd if=/dev/zero of=/var/lib/libvirt/images/foo.img count=1 bs=10M % virsh pool-refresh default % valgrind -v --leak-check=full virsh vol-path --vol \ /var/lib/libvirt/images/foo.img * actual results: Detected in valgrind run: ==16436== 32 bytes in 1 blocks are definitely lost in loss record 7 of 22 ==16436== at 0x4A05FDE: malloc (vg_replace_malloc.c:236) ==16436== by 0x386A314B3D: xdr_string (in /lib64/libc-2.12.so) ==16436== by 0x3DF8CD770D: xdr_remote_nonnull_string (remote_protocol.c:3 ==16436== by 0x3DF8CD7EC8: xdr_remote_storage_vol_get_path_ret % virsh pool-refresh default % valgrind -v --leak-check=full virsh vol-path --vol \ /var/lib/libvirt/images/foo.img Signed-off-by: Alex Jia --- src/libvirt.c | 3 ++- tools/virsh.c | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 988320447b..eeaf0b6145 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -11860,7 +11860,8 @@ error: * pool documentation for information on getting the * persistent naming * - * Returns the storage volume path, or NULL on error + * Returns the storage volume path, or NULL on error. The + * caller must free() the returned path after use. */ char * virStorageVolGetPath(virStorageVolPtr vol) diff --git a/tools/virsh.c b/tools/virsh.c index 57aded30b7..61f69f05bc 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -9320,6 +9320,7 @@ cmdVolPath(vshControl *ctl, const vshCmd *cmd) { virStorageVolPtr vol; const char *name = NULL; + char * StorageVolPath; if (!vshConnectionUsability(ctl, ctl->conn)) return false; @@ -9328,7 +9329,13 @@ cmdVolPath(vshControl *ctl, const vshCmd *cmd) return false; } - vshPrint(ctl, "%s\n", virStorageVolGetPath(vol)); + if ((StorageVolPath = virStorageVolGetPath(vol)) == NULL) { + virStorageVolFree(vol); + return false; + } + + vshPrint(ctl, "%s\n", StorageVolPath); + VIR_FREE(StorageVolPath); virStorageVolFree(vol); return true; }