The function virDomainVcpuPinDel() used vcpupin_list to stand for def->cputune.vcpupin, which made the codes more readable. However, in this function, it will realloc vcpupin_list later. As the definition of realloc(), it may free vcpupin_list and then points it to a new-realloced address, but def->cputune.vcpupin doesn't point to the new address(it's freed however). Thus, 1) When we refer to the def->cputune.vcpupin afterwards, which was freed by realloc(), an INVALID READ occurs, and libvirtd may crash. 2) As no one will use vcpupin_list any more, and no one frees it(it's just alloced by realloc()), memory leak occurs. Part of the valgrind logs are shown as below: ==1837== Thread 15: ==1837== Invalid read of size 8 ==1837== at 0x5367337: virDomainDefFormatInternal (domain_conf.c:18392) which is : virBufferAsprintf(buf, "<vcpupin vcpu='%u' ", def->cputune.vcpupin[i]->vcpuid); ==1837== by 0x536966C: virDomainObjFormat (domain_conf.c:18970) ==1837== by 0x5369743: virDomainSaveStatus (domain_conf.c:19166) ==1837== by 0x117B26DC: qemuDomainPinVcpuFlags (qemu_driver.c:4586) ==1837== by 0x53EA313: virDomainPinVcpuFlags (libvirt.c:9803) ==1837== by 0x14CB7D: remoteDispatchDomainPinVcpuFlags (remote_dispatch.h:6762) ==1837== by 0x14CC81: remoteDispatchDomainPinVcpuFlagsHelper (remote_dispatch.h:6740) ==1837== by 0x5464C30: virNetServerProgramDispatchCall (virnetserverprogram.c:437) ==1837== by 0x546507A: virNetServerProgramDispatch (virnetserverprogram.c:307) ==1837== by 0x171B83: virNetServerProcessMsg (virnetserver.c:172) ==1837== by 0x171E6E: virNetServerHandleJob (virnetserver.c:193) ==1837== by 0x5318E78: virThreadPoolWorker (virthreadpool.c:145) ==1837== Address 0x12ea2870 is 0 bytes inside a block of size 16 free'd ==1837== at 0x4C291AC: realloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==1837== by 0x52A3D14: virReallocN (viralloc.c:245) ==1837== by 0x52A3DFB: virShrinkN (viralloc.c:372) ==1837== by 0x52A3F57: virDeleteElementsN (viralloc.c:503) ==1837== by 0x533939E: virDomainVcpuPinDel (domain_conf.c:15405) //doReset为true时才会进到。 ==1837== by 0x117B2642: qemuDomainPinVcpuFlags (qemu_driver.c:4573) ==1837== by 0x53EA313: virDomainPinVcpuFlags (libvirt.c:9803) ==1837== by 0x14CB7D: remoteDispatchDomainPinVcpuFlags (remote_dispatch.h:6762) ==1837== by 0x14CC81: remoteDispatchDomainPinVcpuFlagsHelper (remote_dispatch.h:6740) ==1837== by 0x5464C30: virNetServerProgramDispatchCall (virnetserverprogram.c:437) ==1837== by 0x546507A: virNetServerProgramDispatch (virnetserverprogram.c:307) ==1837== by 0x171B83: virNetServerProcessMsg (virnetserver.c:172) Steps to reproduce the problem: 1) use virDomainPinVcpuFlags() to pin a guest's vcpu to all the pcpus of the host. This patch uses def->cputune.vcpupin instead of vcpupin_list to do the realloc() job, to avoid invalid read or memory leaking. Signed-off-by: Zhang Bo <oscar.zhangbo@xxxxxxxxxx> Signed-off-by: Yue Wenyuan <yuewenyuan@xxxxxxxxxx@huawei.com> --- src/conf/domain_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f0b715d..e1a3024 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -16276,7 +16276,7 @@ virDomainVcpuPinDel(virDomainDefPtr def, int vcpu) if (vcpupin_list[n]->vcpuid == vcpu) { virBitmapFree(vcpupin_list[n]->cpumask); VIR_FREE(vcpupin_list[n]); - VIR_DELETE_ELEMENT(vcpupin_list, n, def->cputune.nvcpupin); + VIR_DELETE_ELEMENT(def->cputune.vcpupin, n, def->cputune.nvcpupin); return; } } -- 1.7.12.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list