On 19.09.2016 08:32, Peter Krempa wrote: > On Mon, Sep 19, 2016 at 07:55:47 +0200, Michal Privoznik wrote: >> When trying to migrate a huge page enabled guest, I've noticed >> the following crash. Apparently, if no specific hugepages are >> requested: >> >> <memoryBacking> >> <hugepages/> >> </memoryBacking> >> >> and there are no hugepages configured on the destination, we try >> to dereference a NULL pointer. >> >> Program received signal SIGSEGV, Segmentation fault. >> 0x00007fcc907fb20e in qemuGetHugepagePath (hugepage=0x0) at qemu/qemu_conf.c:1447 >> 1447 if (virAsprintf(&ret, "%s/libvirt/qemu", hugepage->mnt_dir) < 0) >> (gdb) bt >> #0 0x00007fcc907fb20e in qemuGetHugepagePath (hugepage=0x0) at qemu/qemu_conf.c:1447 >> #1 0x00007fcc907fb2f5 in qemuGetDefaultHugepath (hugetlbfs=0x0, nhugetlbfs=0) at qemu/qemu_conf.c:1466 >> #2 0x00007fcc907b4afa in qemuBuildMemoryBackendStr (size=4194304, pagesize=0, guestNode=0, userNodeset=0x0, autoNodeset=0x0, def=0x7fcc70019070, qemuCaps=0x7fcc70004000, cfg=0x7fcc5c011800, backendType=0x7fcc95087228, backendProps=0x7fcc95087218, >> force=false) at qemu/qemu_command.c:3297 >> #3 0x00007fcc907b4f91 in qemuBuildMemoryCellBackendStr (def=0x7fcc70019070, qemuCaps=0x7fcc70004000, cfg=0x7fcc5c011800, cell=0, auto_nodeset=0x0, backendStr=0x7fcc70020360) at qemu/qemu_command.c:3413 >> #4 0x00007fcc907c0406 in qemuBuildNumaArgStr (cfg=0x7fcc5c011800, def=0x7fcc70019070, cmd=0x7fcc700040c0, qemuCaps=0x7fcc70004000, auto_nodeset=0x0) at qemu/qemu_command.c:7470 >> #5 0x00007fcc907c5fdf in qemuBuildCommandLine (driver=0x7fcc5c07b8a0, logManager=0x7fcc70003c00, def=0x7fcc70019070, monitor_chr=0x7fcc70004bb0, monitor_json=true, qemuCaps=0x7fcc70004000, migrateURI=0x7fcc700199c0 "defer", snapshot=0x0, >> vmop=VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START, standalone=false, enableFips=false, nodeset=0x0, nnicindexes=0x7fcc95087498, nicindexes=0x7fcc950874a0, domainLibDir=0x7fcc700047c0 "/var/lib/libvirt/qemu/domain-1-fedora") at qemu/qemu_command.c:9547 > > I think you can trim the backtrace here. Okay, >> --- >> src/qemu/qemu_command.c | 6 ++++++ >> 1 file changed, 6 insertions(+) >> >> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c >> index 038c38f..0bafc3f 100644 >> --- a/src/qemu/qemu_command.c >> +++ b/src/qemu/qemu_command.c >> @@ -3294,6 +3294,12 @@ qemuBuildMemoryBackendStr(unsigned long long size, >> if (!(mem_path = qemuGetHugepagePath(&cfg->hugetlbfs[i]))) >> goto cleanup; >> } else { >> + if (!cfg->nhugetlbfs) { >> + virReportError(VIR_ERR_INTERNAL_ERROR, >> + "%s", _("hugetlbfs filesystem is not mounted " >> + "or disabled by administrator config")); >> + goto cleanup; >> + } >> if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs, >> cfg->nhugetlbfs))) > > I think the bug is in qemuGetDefaultHugepath function rather than the > caller: > > char * > qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs, > size_t nhugetlbfs) > { > size_t i; > > for (i = 0; i < nhugetlbfs; i++) > if (hugetlbfs[i].deflt) > break; > > if (i == nhugetlbfs) > i = 0; > > return qemuGetHugepagePath(&hugetlbfs[i]); > > ^^ it dereferences the first member of the first argument even if you > explicitly specify that the array has 0 elements. That i = 0 assignment does not state array size, it just picks the first element in the array if no explicitly set default huge page size is found. > > } > > If you want to go with the fix as in this patch then you'll need to add > a comment to qemuGetDefaultHugepath that the callers should make sure > that it's called with at least one hugepage entry. Or fix > qemuGetDefaultHugepath rathr than working it around in the caller. Well, after my 2nd patch, there's no other caller than a fixed one. And I think qemuGetDefaultHugepath is really designed to be just a simple function to fetch caller the path to huge pages. But okay, I can discard 2/2 and basically move out its internals to various other functions (like qemuGetDefaultHugepath). Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list