----- Forwarded message from 李强 <liqiang...@360.cn> ----- Date: Fri, 22 Jul 2016 03:48:38 +0000 From: 李强 <liqiang...@360.cn> To: "Michael S. Tsirkin" <m...@redhat.com> Subject: 答复: Host memory leakage in QEMU xhci device emulation Message-ID: <143c0afc63fc204cb0c55bb88f3a8abb0181d...@ex02.corp.qihoo.net> In-Reply-To: <20160722063935-mutt-send-email-...@kernel.org>
Right, a user can hotplug a lot of devices. It is a bug not a security issue. Just publish it. > -----邮件原件----- > 发件人: Michael S. Tsirkin [mailto:m...@redhat.com] > 发送时间: 2016年7月22日 11:42 > 收件人: 李强 > 抄送: pmato...@redhat.com; sstabell...@kernel.org; secal...@redhat.com; > mdr...@linux.vnet.ibm.com > 主题: Re: Host memory leakage in QEMU xhci device emulation > > On Fri, Jul 22, 2016 at 02:42:56AM +0000, 李强 wrote: > > Hi, > > > > > > > > I found a host memory leakage issue in QEMU hcd-xhci device emulation. > > > > > > > > DESCRIPTION > > > > _____ > > > > > > > > In usb_xhci_realize() function, it calls msix_init() which requires > > memory malloc. In usb_xhci_exit(), it doesn't call the corresponding > > function > > msix_uninit() to free the memory. > > > > This will cause host memory leakage if a malicious hotplug and unplug > > the xhci device. > > Thanks for the resport. > > I would say whoever can hotplug devices can just hotplug a hoge number of > these until you run out of memory. > So I don't think it's a security vulnerability, but we should fix it. > > Do you agree? If yes we can publish this on the qemu mailing list. > > > > > > > > code from hw/usb/hcd-xhci.c > > > > static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) > > > > { > > > > int i, ret; > > > > > > > > if (xhci_get_flag(xhci, XHCI_FLAG_USE_MSI_X)) { > > > > msix_init(dev, xhci->numintrs, > > > > &xhci->mem, 0, OFF_MSIX_TABLE, > > > > &xhci->mem, 0, OFF_MSIX_PBA, > > > > 0x90); > > > > } > > > > } > > > > > > > > static void usb_xhci_exit(PCIDevice *dev) > > > > { > > > > int i; > > > > XHCIState *xhci = XHCI(dev); > > > > > > > > trace_usb_xhci_exit(); > > > > > > > > for (i = 0; i < xhci->numslots; i++) { > > > > xhci_disable_slot(xhci, i + 1); > > > > } > > > > > > > > if (xhci->mfwrap_timer) { > > > > timer_del(xhci->mfwrap_timer); > > > > timer_free(xhci->mfwrap_timer); > > > > xhci->mfwrap_timer = NULL; > > > > } > > > > > > > > /* destroy msix memory region *///here just destroy the memory > > region, doesn’t free the msix memory > > > > if (dev->msix_table && dev->msix_pba > > > > && dev->msix_entry_used) { > > > > memory_region_del_subregion(&xhci->mem, > > &dev->msix_table_mmio); > > > > memory_region_del_subregion(&xhci->mem, > &dev->msix_pba_mmio); > > > > } > > > > > > > > usb_bus_release(&xhci->bus); > > > > } > > > > > > > > DEBUG AND TEST INFO > > > > _____ > > > > > > > > Breakpoint 1, usb_xhci_realize (dev=0x5555592e7c20, > > errp=0x7fffffffc5f8) at hw/ > > usb/hcd-xhci.c:3652 > > > > 3652 msix_init(dev, xhci->numintrs, > > > > (gdb) p dev->msix_table > > > > $1 = (uint8_t *) 0x0 > > > > (gdb) p dev->msix_pba > > > > $2 = (uint8_t *) 0x0 > > > > (gdb) p dev->msix_entry_used > > > > $3 = (unsigned int *) 0x0 > > > > (gdb) n > > > > [Thread 0x7fffe72f7700 (LWP 49433) exited] > > > > 3657 } > > > > (gdb) p dev->msix_table > > > > $4 = (uint8_t *) 0x55555823a480 "" > > > > (gdb) p dev->msix_pba > > > > $5 = (uint8_t *) 0x55555823a590 "" > > > > (gdb) p dev->msix_entry_used > > > > $6 = (unsigned int *) 0x55555823a5b0 > > > > (gdb) c > > > > Continuing. > > > > > > > > Program received signal SIGPIPE, Broken pipe. > > > > 0x00007ffff69ed78d in sendmsg () at > > ../sysdeps/unix/syscall-template.S:81 > > > > 81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS) > > > > (gdb) i b > > > > Num Type Disp Enb Address What > > > > 1 breakpoint keep y 0x00005555559c6a68 in > usb_xhci_realize at hw/ > > usb/hcd-xhci.c:3652 > > > > breakpoint already hit 1 time > > > > 2 breakpoint keep y 0x00005555559c6c5e in usb_xhci_exit > at hw/usb/ > > hcd-xhci.c:3686 > > > > (gdb) d 1 > > > > (gdb) c > > > > Continuing. > > > > [New Thread 0x7fffe72f7700 (LWP 49451)] > > > > [Switching to Thread 0x7fffe5a04700 (LWP 49408)] > > > > > > > > Breakpoint 2, usb_xhci_exit (dev=0x5555592e7c20) at > > hw/usb/hcd-xhci.c:3687 > > > > 3687 if (dev->msix_table && dev->msix_pba > > > > (gdb) p dev->msix_table > > > > $7 = (uint8_t *) 0x55555823a480 "\f\020\340\376" > > > > (gdb) p dev->msix_pba > > > > $8 = (uint8_t *) 0x55555823a590 "" > > > > (gdb) p dev->msix_entry_used > > > > $9 = (unsigned int *) 0x55555823a5b0 > > > > (gdb) n > > > > 3688 && dev->msix_entry_used) { > > > > (gdb) n > > > > 3689 memory_region_del_subregion(&xhci->mem, > &dev-> > > msix_table_mmio); > > > > (gdb) awatch *(int*)0x55555823a480 // this three > breakpoint never > > triggered > > > > Hardware access (read/write) watchpoint 3: *(int*)0x55555823a480 > > > > (gdb) awatch *(int*)0x55555823a590 > > > > Hardware access (read/write) watchpoint 4: *(int*)0x55555823a590 > > > > (gdb) awatch *(int*)0x55555823a5b0 > > > > Hardware access (read/write) watchpoint 5: *(int*)0x55555823a5b0 > > > > (gdb) c > > > > Continuing. > > > > [Thread 0x7fffe72f7700 (LWP 49451) exited] > > > > [New Thread 0x7fffe72f7700 (LWP 49468)] > > > > > > > > > > > > I use a script modified from https://gist.github.com/sibiaoluo/9798832 > > to send qmp commands. > > > > The script is in attachment. We can see the memory usage is raising. > > > > > > > > PID USER PR NI VIRT RES SHR S %CPU %MEM > TIME+ > > COMMAND > > > > 48833 root 20 0 2735700 2.057g 5152 R 149.0 70.3 34:42.56 > > qemu-system-x86 > > > > > > > > REPRODUCE > > > > _____ > > > > > > > > command used:gdb --args ./qemu-system-x86_64 -m 2048 -hda > > /root/centos6.img -enable-kvm -qmp unix:/tmp/qmp-socket,server,nowait > > > > > > > > Then run the attachment script, it will show the qemu process memory > > usage is raising. > > > > > > > > TEST ENVIRONMENT > > > > _____ > > > > > > > > CentOS 7 x64 > > > > http://wiki.qemu-project.org/download/qemu-2.6.0.tar.bz2 > > > > > > > > Thanks, > > > > > > > > Li Qiang of the Cloud Security Team, Qihoo 360 Inc. > > > ----- End forwarded message -----