[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] memory corruption in HYPERVISOR_physdev_op()
On Mon, 2012-10-15 at 11:48 +0100, Jan Beulich wrote: > >>> On 15.10.12 at 12:27, Ian Campbell <Ian.Campbell@xxxxxxxxxx> wrote: > > On Fri, 2012-09-14 at 14:24 +0300, Dan Carpenter wrote: > >> My static analyzer complains about potential memory corruption in > >> HYPERVISOR_physdev_op() > >> > >> arch/x86/include/asm/xen/hypercall.h > >> 389 static inline int > >> 390 HYPERVISOR_physdev_op(int cmd, void *arg) > >> 391 { > >> 392 int rc = _hypercall2(int, physdev_op, cmd, arg); > >> 393 if (unlikely(rc == -ENOSYS)) { > >> 394 struct physdev_op op; > >> 395 op.cmd = cmd; > >> 396 memcpy(&op.u, arg, sizeof(op.u)); > >> 397 rc = _hypercall1(int, physdev_op_compat, &op); > >> 398 memcpy(arg, &op.u, sizeof(op.u)); > >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > >> Some of the arg buffers are not as large as sizeof(op.u) which is either > >> 12 or 16 depending on the size of longs in struct physdev_apic. > > > > Nasty! > > Wasn't it that pv-ops expects Xen 4.0.1 or newer anyway? If so, > what does this code exist for in the first place (it's framed by > #if CONFIG_XEN_COMPAT <= 0x030002 in the Xenified kernel)? I think the 4.0.1 or newer requirement is for dom0 only. I guess physdev op is only used in dom0 though? Or does passthrough need it? > > >> 399 } > >> 400 return rc; > >> 401 } > >> > >> One example of this is in xen_initdom_restore_msi_irqs(). > >> > >> arch/x86/pci/xen.c > >> 337 struct physdev_pci_device restore_ext; > >> 338 > >> 339 restore_ext.seg = pci_domain_nr(dev->bus); > >> 340 restore_ext.bus = dev->bus->number; > >> 341 restore_ext.devfn = dev->devfn; > >> 342 ret = > > HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi_ext, > >> 343 &restore_ext); > >> ^^^^^^^^^^^^ > >> There are only 4 bytes here. > >> > >> 344 if (ret == -ENOSYS) > >> ^^^^^^^^^^^^^^ > >> If we hit this condition, we have corrupted some memory. > > > > I can see the memory corruption but how does it relate to ret == > > -ENOSYS? > > The (supposedly) corrupting code site inside an > > if (unlikely(rc == -ENOSYS)) { Ah, for some reason I assumed this was in the eventual caller, even though it was staring me right in the face in the full quote. > Supposedly because as long as the argument passed to the > function is in memory accessed by the local CPU only and > doesn't overlap with storage used for "rc" (e.g. living in a > register), there's no corruption possible afaict - the second > memcpy() would just copy back what the first one obtained > from there. > > Fixing this other than by removing the broken code would be > pretty hard I'm afraid (and I tend to leave the code untouched > altogether in the Xenified tree). Given that it is compat code the list of subops which needs to supported in this case is small and finite so a simple lookup table or even switch stmt for the size might be an option. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |