Skip to contentSkip to conversation

usb: dwc3: host: fix props[] overflow and dangling xhci pointer on error

PATCH In review David Collin 2 participants 6 messages Sep 4 – Sep 11

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: dwc3: host: fix props[] overflow and dangling xhci pointer on error

props[] is sized for exactly the number of properties dwc3_host_init() can populate, leaving no slot for the NULL terminator property_entries_dup() requires when usb3_lpm_capable, usb2_lpm_disable, and the <=3.00a PED quirk are all true. Size props[] for one more slot.

This also clears dwc->xhci on the error path and adds a NULL check in dwc3_host_exit(), since a failed dwc3_host_init() otherwise leaves a dangling pointer that dwc3_host_exit() dereferences unconditionally on removal/shutdown.

Fixes 8da7644493b4 ("usb: dwc3: Specify maximum number of XHCI interrupters")
---
 drivers/usb/dwc3/host.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/dwc3/host.c +5 -1
index c5674161b..cd1e5204a 100644
@@ -130,7 +130,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc)
 
 int dwc3_host_init(struct dwc3 *dwc)
 {
-	struct property_entry	props[6];
+	struct property_entry	props[7];
 	struct platform_device	*xhci;
 	int			ret, irq;
 	int			prop_idx = 0;
@@ -219,12 +219,16 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err:
 	platform_device_put(xhci);
+	dwc->xhci = NULL;
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dwc3_host_init);
 
 void dwc3_host_exit(struct dwc3 *dwc)
 {
+	if (!dwc->xhci)
+		return;
+
 	if (dwc->sys_wakeup)
 		device_init_wakeup(&dwc->xhci->dev, false);
 
Signature · 1 line
2.55.0
maintainer
#1 lore raw

Hi,

Quoted 52 lines · David Collin

props[] is sized for exactly the number of properties dwc3_host_init() can populate, leaving no slot for the NULL terminator property_entries_dup() requires when usb3_lpm_capable, usb2_lpm_disable, and the <=3.00a PED quirk are all true. Size props[] for one more slot.

This also clears dwc->xhci on the error path and adds a NULL check in dwc3_host_exit(), since a failed dwc3_host_init() otherwise leaves a dangling pointer that dwc3_host_exit() dereferences unconditionally on removal/shutdown.

Fixes 8da7644493b4 ("usb: dwc3: Specify maximum number of XHCI interrupters")
---
 drivers/usb/dwc3/host.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/dwc3/host.c +5 -1
index c5674161b..cd1e5204a 100644
@@ -130,7 +130,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc)
 
 int dwc3_host_init(struct dwc3 *dwc)
 {
-	struct property_entry	props[6];
+	struct property_entry	props[7];
 	struct platform_device	*xhci;
 	int			ret, irq;
 	int			prop_idx = 0;
@@ -219,12 +219,16 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err:
 	platform_device_put(xhci);
+	dwc->xhci = NULL;
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dwc3_host_init);
 
 void dwc3_host_exit(struct dwc3 *dwc)
 {
+	if (!dwc->xhci)
+		return;
+
 	if (dwc->sys_wakeup)
 		device_init_wakeup(&dwc->xhci->dev, false);
 
Signature · 1 line
2.55.0

These are two separate fixes. Can you split your change into separate patches with the corresponding Fixes tag for each? Also, please add Cc stable tag.

Thanks,
Thinh

#2 lore raw

PATCH v2 1/2 usb: dwc3: host: fix dangling xhci pointer on init failure

dwc3_host_init()'s error path frees xhci via platform_device_put() but never clears dwc->xhci, leaving a dangling pointer that dwc3_host_exit() dereferences unconditionally on removal/shutdown. Clear dwc->xhci on the error path and return early from dwc3_host_exit() if NULL.

Fixes d07e8819a03d ("usb: dwc3: add xHCI Host support")
---
 drivers/usb/dwc3/host.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/usb/dwc3/host.c +4 -0
index c5674161b2b0..74117cbb2f42 100644
@@ -219,12 +219,16 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err:
 	platform_device_put(xhci);
+	dwc->xhci = NULL;
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dwc3_host_init);
 
 void dwc3_host_exit(struct dwc3 *dwc)
 {
+	if (!dwc->xhci)
+		return;
+
 	if (dwc->sys_wakeup)
 		device_init_wakeup(&dwc->xhci->dev, false);
 
Signature · 1 line
2.55.0
#3 lore raw

PATCH v2 2/2 usb: dwc3: host: fix props[] overflow when all quirks are enabled

props[] is sized for exactly the number of properties dwc3_host_init() can populate, leaving no slot for the NULL terminator property_entries_dup() requires when usb3_lpm_capable, usb2_lpm_disable, and the <=3.00a PED quirk are all true. Size props[] for one more slot.

Fixes 8da7644493b4 ("usb: dwc3: Specify maximum number of XHCI interrupters")
---
 drivers/usb/dwc3/host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/dwc3/host.c +1 -1
index 74117cbb2f42..cd1e5204ac3a 100644
@@ -130,7 +130,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc)
 
 int dwc3_host_init(struct dwc3 *dwc)
 {
-	struct property_entry	props[6];
+	struct property_entry	props[7];
 	struct platform_device	*xhci;
 	int			ret, irq;
 	int			prop_idx = 0;
Signature · 1 line
2.55.0
maintainer Acked-by on v2 2/2
#4 lore raw

Re: [PATCH v2 2/2] usb: dwc3: host: fix props[] overflow when all quirks are enabled

Quoted 29 lines · David Collin

props[] is sized for exactly the number of properties dwc3_host_init() can populate, leaving no slot for the NULL terminator property_entries_dup() requires when usb3_lpm_capable, usb2_lpm_disable, and the <=3.00a PED quirk are all true. Size props[] for one more slot.

Fixes 8da7644493b4 ("usb: dwc3: Specify maximum number of XHCI interrupters")
---
 drivers/usb/dwc3/host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/dwc3/host.c +1 -1
index 74117cbb2f42..cd1e5204ac3a 100644
@@ -130,7 +130,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc)
 
 int dwc3_host_init(struct dwc3 *dwc)
 {
-	struct property_entry	props[6];
+	struct property_entry	props[7];
 	struct platform_device	*xhci;
 	int			ret, irq;
 	int			prop_idx = 0;
Signature · 1 line
2.55.0

Thanks,
Thinh

maintainer Acked-by on v2 1/2
#5 lore raw

Re: [PATCH v2 1/2] usb: dwc3: host: fix dangling xhci pointer on init failure

In reply to David Collin
Quoted 37 lines · David Collin

dwc3_host_init()'s error path frees xhci via platform_device_put() but never clears dwc->xhci, leaving a dangling pointer that dwc3_host_exit() dereferences unconditionally on removal/shutdown. Clear dwc->xhci on the error path and return early from dwc3_host_exit() if NULL.

Fixes d07e8819a03d ("usb: dwc3: add xHCI Host support")
---
 drivers/usb/dwc3/host.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/usb/dwc3/host.c +4 -0
index c5674161b2b0..74117cbb2f42 100644
@@ -219,12 +219,16 @@ int dwc3_host_init(struct dwc3 *dwc)
 	return 0;
 err:
 	platform_device_put(xhci);
+	dwc->xhci = NULL;
 	return ret;
 }
 EXPORT_SYMBOL_GPL(dwc3_host_init);
 
 void dwc3_host_exit(struct dwc3 *dwc)
 {
+	if (!dwc->xhci)
+		return;
+
 	if (dwc->sys_wakeup)
 		device_init_wakeup(&dwc->xhci->dev, false);
 
Signature · 1 line
2.55.0

Thanks,
Thinh