From f7e7874d9b0df07072c021dfba37e25870fe6d93 Mon Sep 17 00:00:00 2001 From: RD Babiera Date: Tue, 5 Sep 2023 22:07:07 +0000 Subject: [PATCH] BACKPORT: usb: typec: bus: verify partner exists in typec_altmode_attention Some usb hubs will negotiate DisplayPort Alt mode with the device but will then negotiate a data role swap after entering the alt mode. The data role swap causes the device to unregister all alt modes, however the usb hub will still send Attention messages even after failing to reregister the Alt Mode. type_altmode_attention currently does not verify whether or not a device's altmode partner exists, which results in a NULL pointer error when dereferencing the typec_altmode and typec_altmode_ops belonging to the altmode partner. Verify the presence of a device's altmode partner before sending the Attention message to the Alt Mode driver. Fixes: 8a37d87d72f0 ("usb: typec: Bus type for alternate modes") Cc: stable@vger.kernel.org Signed-off-by: RD Babiera Reviewed-by: Heikki Krogerus Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230814180559.923475-1-rdbabiera@google.com Signed-off-by: Greg Kroah-Hartman Bug: 288952921 (cherry picked from commit f23643306430f86e2f413ee2b986e0773e79da31) [rd: changed return type of typec_altmode_attention to void to not break kmi, moved tcpm_log from error return to typec_altmode_attention as dev_warn] Signed-off-by: RD Babiera (cherry picked from https://android-review.googlesource.com/q/commit:e23c89c0b76305f9f264ba113d647710b956a540) Merged-In: I054a6ef56b9b2d7c4e8167e8630a8c277910da88 Change-Id: I054a6ef56b9b2d7c4e8167e8630a8c277910da88 --- drivers/usb/typec/bus.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index 31c2a3130cad..ef79217a903f 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -156,7 +156,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit); */ void typec_altmode_attention(struct typec_altmode *adev, u32 vdo) { - struct typec_altmode *pdev = &to_altmode(adev)->partner->adev; + struct altmode *partner = to_altmode(adev)->partner; + struct typec_altmode *pdev; + + /* + * If partner is NULL then a NULL pointer error occurs when + * dereferencing pdev and its operations. The original upstream commit + * changes the return type so the tcpm can log when this occurs, but + * due to KMI restrictions we can only silently prevent the error for + * now. + */ + if (!partner) + return; + + pdev = &partner->adev; if (pdev->ops && pdev->ops->attention) pdev->ops->attention(pdev, vdo);