mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2026-06-25 11:43:20 +02:00
xhci: Don't add a virt_dev to the devs array before it's fully allocated
commit 5d9b70f7d5 upstream.
Avoid null pointer dereference if some function is walking through the
devs array accessing members of a new virt_dev that is mid allocation.
Add the virt_dev to xhci->devs[i] _after_ the virt_device and all its
members are properly allocated.
issue found by KASAN: null-ptr-deref in xhci_find_slot_id_by_port
"Quick analysis suggests that xhci_alloc_virt_device() is not mutex
protected. If so, there is a time frame where xhci->devs[slot_id] is set
but not fully initialized. Specifically, xhci->devs[i]->udev can be NULL."
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: There is an extra failure path, so we may need to
free dev->eps[0].ring]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
This commit is contained in:
parent
f95ea9d198
commit
3a70d5ab61
|
|
@ -873,10 +873,9 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags);
|
||||
if (!xhci->devs[slot_id])
|
||||
dev = kzalloc(sizeof(*dev), flags);
|
||||
if (!dev)
|
||||
return 0;
|
||||
dev = xhci->devs[slot_id];
|
||||
|
||||
/* Allocate the (output) device context that will be used in the HC. */
|
||||
dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
|
||||
|
|
@ -925,9 +924,19 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
|
|||
&xhci->dcbaa->dev_context_ptrs[slot_id],
|
||||
le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id]));
|
||||
|
||||
xhci->devs[slot_id] = dev;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
xhci_free_virt_device(xhci, slot_id);
|
||||
|
||||
if (dev->eps[0].ring)
|
||||
xhci_ring_free(xhci, dev->eps[0].ring);
|
||||
if (dev->in_ctx)
|
||||
xhci_free_container_ctx(xhci, dev->in_ctx);
|
||||
if (dev->out_ctx)
|
||||
xhci_free_container_ctx(xhci, dev->out_ctx);
|
||||
kfree(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user