usb: typec: bus: verify partner exists in typec_altmode_attention
Subsystems (5)
PATCH v4 1/1 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.
---
Changes since v1:
* Only assigns pdev if altmode partner exists in typec_altmode_attention
* Removed error return in typec_altmode_attention if Alt Mode does not implement Attention messages.
* Changed tcpm_log message to indicate that altmode partner does not exist, as it only logs in that case.
---
Changes since v2:
* Changed tcpm_log message to accurately reflect error
* Revised commit message
---
Changes since v3:
* Fixed nits
--- drivers/usb/typec/bus.c | 12 ++++++++++-- drivers/usb/typec/tcpm/tcpm.c | 3 ++- include/linux/usb/typec_altmode.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-)
drivers/usb/typec/bus.c +10 -2
@@ -183,12 +183,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit);* * Notifies the partner of @adev about Attention command. */ -void typec_altmode_attention (struct typec_altmode *adev,u32 vdo) +int 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) +return -ENODEV ; + + pdev = &partner->adev;if (pdev->ops && pdev->ops->attention) pdev->ops->attention (pdev, vdo); + +return 0 ; }EXPORT_SYMBOL_GPL (typec_altmode_attention);
drivers/usb/typec/tcpm/tcpm.c +2 -1
@@ -1877,7 +1877,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, }break ;case ADEV_ATTENTION : -typec_altmode_attention (adev, p[1 ]); +if (typec_altmode_attention (adev, p[1 ])) +tcpm_log (port,"typec_altmode_attention no port partner altmode" );break ; } }
include/linux/usb/typec_altmode.h +1 -1
@@ -67,7 +67,7 @@ struct typec_altmode_ops {int typec_altmode_enter (struct typec_altmode *altmode,u32 *vdo);int typec_altmode_exit (struct typec_altmode *altmode); -void typec_altmode_attention (struct typec_altmode *altmode,u32 vdo); +int typec_altmode_attention (struct typec_altmode *altmode,u32 vdo);int typec_altmode_vdm (struct typec_altmode *altmode,const u32 header,const u32 *vdo,int count); int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
base-commit: f176638af476c6d46257cc3303f5c7cf47d5967d
Signature · 1 line
2.41.0.694.ge786442a9b-goog
Quoted 10 lines · RD Babiera
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_attentioncurrently does not verify whether or not a device's altmode partner exists, which results in a NULL pointer error when dereferencing thetypec_altmodeandtypec_altmode_opsbelonging to the altmode partner.
Quoted 6 lines
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")Signed-off-by RD Babiera <[email protected]>
Quoted 78 lines
---
Changes since v1:
* Only assigns pdev if altmode partner exists intypec_altmode_attention
* Removed error return intypec_altmode_attentionif Alt Mode does not implement Attention messages.
* Changedtcpm_logmessage to indicate that altmode partner does not exist, as it only logs in that case.
---
Changes since v2:
* Changedtcpm_logmessage to accurately reflect error
* Revised commit message
---
Changes since v3:
* Fixed nits--- drivers/usb/typec/bus.c | 12 ++++++++++-- drivers/usb/typec/tcpm/tcpm.c | 3 ++- include/linux/usb/typec_altmode.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-)drivers/usb/typec/bus.c +10
-2@@ -183,12 +183,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit);* * Notifies the partner of @adev about Attention command. */ -void typec_altmode_attention (struct typec_altmode *adev,u32 vdo) +int 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) +return -ENODEV ; + + pdev = &partner->adev;if (pdev->ops && pdev->ops->attention) pdev->ops->attention (pdev, vdo); + +return 0 ; }EXPORT_SYMBOL_GPL (typec_altmode_attention);drivers/usb/typec/tcpm/tcpm.c +2
-1@@ -1877,7 +1877,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, }break ;case ADEV_ATTENTION : -typec_altmode_attention (adev, p[1 ]); +if (typec_altmode_attention (adev, p[1 ])) +tcpm_log (port,"typec_altmode_attention no port partner altmode" );break ; } }include/linux/usb/typec_altmode.h +1
-1@@ -67,7 +67,7 @@ struct typec_altmode_ops {int typec_altmode_enter (struct typec_altmode *altmode,u32 *vdo);int typec_altmode_exit (struct typec_altmode *altmode); -void typec_altmode_attention (struct typec_altmode *altmode,u32 vdo); +int typec_altmode_attention (struct typec_altmode *altmode,u32 vdo);int typec_altmode_vdm (struct typec_altmode *altmode,const u32 header,const u32 *vdo,int count); int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,base-commit:
f176638af476c6d46257cc3303f5c7cf47d5967dSignature · 1 line
2.41.0.694.ge786442a9b-goog
Signature · 1 line
heikki
Quoted 10 lines · RD Babiera
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_attentioncurrently does not verify whether or not a device's altmode partner exists, which results in a NULL pointer error when dereferencing thetypec_altmodeandtypec_altmode_opsbelonging to the altmode partner.
Quoted 6 lines
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")Signed-off-by RD Babiera <[email protected]>
Quoted 79 lines
---
Changes since v1:
* Only assigns pdev if altmode partner exists intypec_altmode_attention
* Removed error return intypec_altmode_attentionif Alt Mode does not implement Attention messages.
* Changedtcpm_logmessage to indicate that altmode partner does not exist, as it only logs in that case.
---
Changes since v2:
* Changedtcpm_logmessage to accurately reflect error
* Revised commit message
---
Changes since v3:
* Fixed nits--- drivers/usb/typec/bus.c | 12 ++++++++++-- drivers/usb/typec/tcpm/tcpm.c | 3 ++- include/linux/usb/typec_altmode.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-)drivers/usb/typec/bus.c +10
-2@@ -183,12 +183,20 @@ EXPORT_SYMBOL_GPL(typec_altmode_exit);* * Notifies the partner of @adev about Attention command. */ -void typec_altmode_attention (struct typec_altmode *adev,u32 vdo) +int 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) +return -ENODEV ; + + pdev = &partner->adev;if (pdev->ops && pdev->ops->attention) pdev->ops->attention (pdev, vdo); + +return 0 ; }EXPORT_SYMBOL_GPL (typec_altmode_attention);drivers/usb/typec/tcpm/tcpm.c +2
-1@@ -1877,7 +1877,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port, }break ;case ADEV_ATTENTION : -typec_altmode_attention (adev, p[1 ]); +if (typec_altmode_attention (adev, p[1 ])) +tcpm_log (port,"typec_altmode_attention no port partner altmode" );break ; } }include/linux/usb/typec_altmode.h +1
-1@@ -67,7 +67,7 @@ struct typec_altmode_ops {int typec_altmode_enter (struct typec_altmode *altmode,u32 *vdo);int typec_altmode_exit (struct typec_altmode *altmode); -void typec_altmode_attention (struct typec_altmode *altmode,u32 vdo); +int typec_altmode_attention (struct typec_altmode *altmode,u32 vdo);int typec_altmode_vdm (struct typec_altmode *altmode,const u32 header,const u32 *vdo,int count); int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,base-commit:
f176638af476c6d46257cc3303f5c7cf47d5967dSignature · 1 line
2.41.0.694.ge786442a9b-goog