Hi,

On 22-08-19 17:48, Schmid, Carsten wrote:
On 22-08-19 17:23, Mathias Nyman wrote:
On 16.8.2019 12.03, Schmid, Carsten wrote:
On driver removal, the platform_device_unregister call
attached through devm_add_action_or_reset was executed
after usb_hcd_pci_remove.
This lead to a use-after-free for the iomem resource of
the xhci-ext-caps driver in the platform removal
because the parent of the resource was freed earlier.

Fix this by reordering of the removal sequence.


Could all this be avoided if usb_hcd_pci_probe()
used managed device resources as well?
(using devm_request_mem_region(), and devm_ioremap_nocache())

This way the iomem resource would be added to the same devres list
as the platform_unregister_call, and the iomem resource should be
released after the platform_device_unregister as devres_release_all()
releases the resources in reverse order.

Yes I believe that that would work.

I don't think so, because xhci_create_intel_xhci_sw_pdev registers it's
resource through platform_device_add_resources which does not use devm_.

The only thing what is done through devm in xhci_create_intel_xhci_sw_pdev is
ret = devm_add_action_or_reset(...)

Right, so if I understand correctly the problem with the current code (before 
your patch)
is:

Probe:
1. usb_hcd_pci_probe() uses request_mem_region()
2. xhci_create_intel_xhci_sw_pde uses platform_device_add_resources() which are 
a child of the previous region

Remove:
3. usb_hcd_pci_remove does release_region() while the child region is still in 
use
4. At end of remove() devm code calls xhci_intel_unregister_pdev

And the problem is we want to swap 3 and 4.

Now if we make usb_hcd_pci_probe() use devm_request_mem_region and drop the 
cleanup from usb_hcd_pci_remove

Probe:
1. usb_hcd_pci_probe() uses devm_request_mem_region(), this registers a 
release_region() with devm as cleanup
2. xhci_create_intel_xhci_sw_pde uses platform_device_add_resources() which are 
a child of the previous region and calls
   devm_add_action_or_reset() to add xhci_intel_unregister_pdev as cleanup

Remove:
3. usb_hcd_pci_remove does nothing of relevance
4. At end of remove() devm code runs and calls the cleanups in reverse order of 
registration! so it calls:
   xhci_intel_unregister_pdev()
   release_region()

Note the trick here is that the devm framework calls devm registered cleanup 
functions in reverse order of their registration, putting things in the right 
order.

Regards,

Hans

Reply via email to