From cdf047825581df7459aa5a8ca02eccd5bc6c0ae7 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 12 May 2010 09:42:07 +0000 Subject: [PATCH] [USBDRIVER] - Implement deregistering HCD in a device manager. Now, the HCI which failed to initialize will be properly freed without calling NULL pointer or crashing with freed memory access. See issue #4813 for more details. svn path=/trunk/; revision=47168 --- .../drivers/usb/nt4compat/usbdriver/devmgr.c | 14 ++++++++++ .../drivers/usb/nt4compat/usbdriver/devmgr.h | 6 +++++ .../drivers/usb/nt4compat/usbdriver/ehci.c | 26 ++++++++++--------- .../drivers/usb/nt4compat/usbdriver/uhci.c | 24 +++++++++-------- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c index 46c12a07fc1..a1357f26f6d 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.c @@ -1457,6 +1457,20 @@ dev_mgr_register_hcd(PUSB_DEV_MANAGER dev_mgr, PHCD hcd) return dev_mgr->hcd_count - 1; } +VOID +dev_mgr_deregister_hcd(PUSB_DEV_MANAGER dev_mgr, UCHAR hcd_id) +{ + UCHAR i; + + if (dev_mgr == NULL || hcd_id >= MAX_HCDS - 1) + return; + + for (i = hcd_id; i < dev_mgr->hcd_count - 1; i++) + dev_mgr->hcd_array[i] = dev_mgr->hcd_array[i + 1]; + + dev_mgr->hcd_count--; +} + BOOLEAN dev_mgr_register_irp(PUSB_DEV_MANAGER dev_mgr, PIRP pirp, PURB purb) { diff --git a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h index c6d22522935..50d3b6fe6d6 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h +++ b/reactos/drivers/usb/nt4compat/usbdriver/devmgr.h @@ -208,6 +208,12 @@ PUSB_DEV_MANAGER dev_mgr, PHCD hcd ); +VOID +dev_mgr_deregister_hcd( +PUSB_DEV_MANAGER dev_mgr, +UCHAR hcd_id +); + NTSTATUS dev_mgr_dispatch( IN PUSB_DEV_MANAGER dev_mgr, diff --git a/reactos/drivers/usb/nt4compat/usbdriver/ehci.c b/reactos/drivers/usb/nt4compat/usbdriver/ehci.c index 56d7d548cdb..0453fb9727a 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/ehci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/ehci.c @@ -271,7 +271,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU BOOLEAN ehci_init_schedule(PEHCI_DEV ehci, PADAPTER_OBJECT padapter); -BOOLEAN ehci_release(PDEVICE_OBJECT pdev); +BOOLEAN ehci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr); static VOID ehci_stop(PEHCI_DEV ehci); @@ -313,7 +313,7 @@ PDEVICE_OBJECT ehci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, PUS PDEVICE_OBJECT ehci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr); -BOOLEAN ehci_delete_device(PDEVICE_OBJECT pdev); +BOOLEAN ehci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr); VOID ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base); @@ -3366,7 +3366,7 @@ ehci_hcd_release(PHCD hcd) ehci = ehci_from_hcd(hcd); pdev_ext = ehci->pdev_ext; - return ehci_release(pdev_ext->pdev_obj); + return ehci_release(pdev_ext->pdev_obj, hcd->dev_mgr); } NTSTATUS @@ -3565,7 +3565,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU if (pdev_ext->padapter == NULL) { //fatal error - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return NULL; } @@ -3584,7 +3584,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU DbgPrint("ehci_alloc(): error assign slot res, 0x%x\n", status); release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return NULL; } @@ -3619,7 +3619,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU DbgPrint("ehci_alloc(): error, can not translate bus address\n"); release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return NULL; } @@ -3638,7 +3638,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU { release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return NULL; } } @@ -3663,7 +3663,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU { release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return NULL; } @@ -3692,7 +3692,7 @@ ehci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU affinity, FALSE) //No float save != STATUS_SUCCESS) { - ehci_release(pdev); + ehci_release(pdev, dev_mgr); return NULL; } @@ -4017,7 +4017,7 @@ ehci_get_capabilities(PEHCI_DEV ehci, PBYTE base) } BOOLEAN -ehci_delete_device(PDEVICE_OBJECT pdev) +ehci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr) { STRING string; UNICODE_STRING symb_name; @@ -4037,6 +4037,8 @@ ehci_delete_device(PDEVICE_OBJECT pdev) IoDeleteSymbolicLink(&symb_name); RtlFreeUnicodeString(&symb_name); + dev_mgr_deregister_hcd(dev_mgr, pdev_ext->ehci->hcd_interf.hcd_get_id(&pdev_ext->ehci->hcd_interf)); + if (pdev_ext->res_list) ExFreePool(pdev_ext->res_list); // not allocated by usb_alloc_mem @@ -4062,7 +4064,7 @@ ehci_stop(PEHCI_DEV ehci) } BOOLEAN -ehci_release(PDEVICE_OBJECT pdev) +ehci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr) { PEHCI_DEVICE_EXTENSION pdev_ext; PEHCI_DEV ehci; @@ -4095,7 +4097,7 @@ ehci_release(PDEVICE_OBJECT pdev) release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - ehci_delete_device(pdev); + ehci_delete_device(pdev, dev_mgr); return FALSE; diff --git a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c index 0ff08970420..857498c4e00 100644 --- a/reactos/drivers/usb/nt4compat/usbdriver/uhci.c +++ b/reactos/drivers/usb/nt4compat/usbdriver/uhci.c @@ -102,7 +102,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU BOOLEAN uhci_init_schedule(PUHCI_DEV uhci, PADAPTER_OBJECT padapter); -BOOLEAN uhci_release(PDEVICE_OBJECT pdev); +BOOLEAN uhci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr); static VOID uhci_stop(PUHCI_DEV uhci); @@ -465,7 +465,7 @@ uhci_create_device(PDRIVER_OBJECT drvr_obj, PUSB_DEV_MANAGER dev_mgr) } BOOLEAN -uhci_delete_device(PDEVICE_OBJECT pdev) +uhci_delete_device(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr) { STRING string; UNICODE_STRING symb_name; @@ -485,6 +485,8 @@ uhci_delete_device(PDEVICE_OBJECT pdev) IoDeleteSymbolicLink(&symb_name); RtlFreeUnicodeString(&symb_name); + dev_mgr_deregister_hcd(dev_mgr, pdev_ext->uhci->hcd_interf.hcd_get_id(&pdev_ext->uhci->hcd_interf)); + if (pdev_ext->res_list) ExFreePool(pdev_ext->res_list); // not allocated by usb_alloc_mem @@ -723,7 +725,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU if (pdev_ext->padapter == NULL) { //fatal error - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return NULL; } @@ -742,7 +744,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU DbgPrint("uhci_alloc(): error assign slot res, 0x%x\n", status); release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return NULL; } @@ -772,7 +774,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU DbgPrint("uhci_alloc(): error, can not translate bus address\n"); release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return NULL; } @@ -791,7 +793,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU { release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return NULL; } } @@ -810,7 +812,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU { release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return NULL; } @@ -848,7 +850,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU FALSE) //No float save != STATUS_SUCCESS) { - uhci_release(pdev); + uhci_release(pdev, dev_mgr); return NULL; } @@ -856,7 +858,7 @@ uhci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU } BOOLEAN -uhci_release(PDEVICE_OBJECT pdev) +uhci_release(PDEVICE_OBJECT pdev, PUSB_DEV_MANAGER dev_mgr) { PDEVICE_EXTENSION pdev_ext; PUHCI_DEV uhci; @@ -892,7 +894,7 @@ uhci_release(PDEVICE_OBJECT pdev) release_adapter(pdev_ext->padapter); pdev_ext->padapter = NULL; - uhci_delete_device(pdev); + uhci_delete_device(pdev, dev_mgr); return FALSE; @@ -3671,7 +3673,7 @@ uhci_hcd_release(struct _HCD * hcd) uhci = uhci_from_hcd(hcd); pdev_ext = uhci->pdev_ext; - return uhci_release(pdev_ext->pdev_obj); + return uhci_release(pdev_ext->pdev_obj, hcd->dev_mgr); } NTSTATUS