usb: typec: ucsi: displayport: Fix OOB altmode array index
Subsystems (3)
PATCH 1/1 usb: typec: ucsi: displayport: Fix OOB altmode array index
The UCSI displayport driver indexes the connector's port altmode array with the GET_CURRENT_CAM response after checking it is not 0xff. The port altmode array is UCSI_MAX_ALTMODES elements long. If the PPM returns an invalid GET_CURRENT_CAM response above UCSI_MAX_ALTMODES and not equal to 0xff, the kernel may crash with an array index OOB error.
Update the UCSI displayport driver to verify the current cam is less than UCSI_MAX_ALTMODES before accessing the port altmode array.
--- drivers/usb/typec/ucsi/displayport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/typec/ucsi/displayport.c +1 -1
@@ -74,7 +74,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) cur =0xff ; } -if (cur !=0xff ) { +if (cur <UCSI_MAX_ALTMODES ) { ret = dp->con->port_altmode[cur] == alt ?0 : -EBUSY ; goto err_unlock; }
base-commit: e1e6e541c5c9cf548e9fdc35fc26808c82074440
Signature · 1 line
2.55.0.860.g4b6b3295ed-goog
Quoted 6 lines · Jameson Thies
The UCSI displayport driver indexes the connector's port altmode array with the
GET_CURRENT_CAMresponse after checking it is not0xff. The port altmode array isUCSI_MAX_ALTMODESelements long. If the PPM returns an invalidGET_CURRENT_CAMresponse aboveUCSI_MAX_ALTMODESand not equal to0xff, the kernel may crash with an array index OOB error.
Quoted 6 lines
Update the UCSI displayport driver to verify the current cam is less than
UCSI_MAX_ALTMODESbefore accessing the port altmode array.Fixes af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")Signed-off-by Jameson Thies <[email protected]>
Quoted 22 lines
--- drivers/usb/typec/ucsi/displayport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/usb/typec/ucsi/displayport.c +1
-1@@ -74,7 +74,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) cur =0xff ; } -if (cur !=0xff ) { +if (cur <UCSI_MAX_ALTMODES ) { ret = dp->con->port_altmode[cur] == alt ?0 : -EBUSY ; goto err_unlock; }base-commit:
e1e6e541c5c9cf548e9fdc35fc26808c82074440Signature · 1 line
2.55.0.860.g4b6b3295ed-goog
Heikki Krogerus
maintainerQuoted 21 lines · Jameson Thies
The UCSI displayport driver indexes the connector's port altmode array with the
GET_CURRENT_CAMresponse after checking it is not0xff. The port altmode array isUCSI_MAX_ALTMODESelements long. If the PPM returns an invalidGET_CURRENT_CAMresponse aboveUCSI_MAX_ALTMODESand not equal to0xff, the kernel may crash with an array index OOB error.Update the UCSI displayport driver to verify the current cam is less than
UCSI_MAX_ALTMODESbefore accessing the port altmode array.Fixes af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")Signed-off-by Jameson Thies <[email protected]>--- drivers/usb/typec/ucsi/displayport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/usb/typec/ucsi/displayport.c +0
-0
drivers/usb/typec/ucsi/displayport.c static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) · line 74
Quoted 1 line
drivers/usb/typec/ucsi/displayport.c +0
-0@@ -74,7 +74,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) cur =0xff ;
Can you remove the above line while at it?
drivers/usb/typec/ucsi/displayport.c static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) · line 77
Quoted 4 lines
drivers/usb/typec/ucsi/displayport.c +1
-1} -if (cur !=0xff ) { +if (cur <UCSI_MAX_ALTMODES ) {
Shouldn't that be the other way around?
drivers/usb/typec/ucsi/displayport.c static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) · line 80
Quoted 3 lines
drivers/usb/typec/ucsi/displayport.c +0
-0ret = dp->con->port_altmode[cur] == alt ?0 : -EBUSY ; goto err_unlock; }
Thanks,
Signature · 1 line
heikki
Quoted 27 lines · Heikki Krogerus
Quoted 21 lines · Jameson Thies
The UCSI displayport driver indexes the connector's port altmode array with the
GET_CURRENT_CAMresponse after checking it is not0xff. The port altmode array isUCSI_MAX_ALTMODESelements long. If the PPM returns an invalidGET_CURRENT_CAMresponse aboveUCSI_MAX_ALTMODESand not equal to0xff, the kernel may crash with an array index OOB error.Update the UCSI displayport driver to verify the current cam is less than
UCSI_MAX_ALTMODESbefore accessing the port altmode array.Fixes af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode")Signed-off-by Jameson Thies <[email protected]>--- drivers/usb/typec/ucsi/displayport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/usb/typec/ucsi/displayport.c +0
-0drivers/usb/typec/ucsi/displayport.c static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) · line 74
Quoted 1 line
drivers/usb/typec/ucsi/displayport.c +0
-0@@ -74,7 +74,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) cur =0xff ;Can you remove the above line while at it?
Quoted 7 lines
drivers/usb/typec/ucsi/displayport.c static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo) · line 77
Quoted 4 lines
drivers/usb/typec/ucsi/displayport.c +1
-1} -if (cur !=0xff ) { +if (cur <UCSI_MAX_ALTMODES ) {Shouldn't that be the other way around?
Looks fine, but shouldn't we return an error if an invalid value is received, similar to the Thunderbolt implementation?
if (cur != 0xff) {
if (cur >= UCSI_MAX_ALTMODES ||
dp->con->port_altmode[cur] != alt)
ret = -EBUSY;
else
ret = 0;
goto err_unlock;Thanks,
Andrei
Hi Heikki and Andrei,
thanks for taking a look. I'll follow up with a v2 of this patch to address your comments. Answers below with some additional comments.
Quoted 1 line
Quoted 1 line
Can you remove the above line while at it?
Will remove in v2.
Quoted 1 line
Quoted 1 line
Shouldn't that be the other way around?
I'm not sure I understand. Because UCSI_MAX_ALTMODES is set to 30 in ucsi.h, verifying 'cur' is less than UCSI_MAX_ALTMODES will still evaluate to false if 'cur' is 0xff. This update maintains the existing functionality and prevents the driver from using an out of bounds index.
Quoted 2 lines
Looks fine, but shouldn't we return an error if an invalid value is received, similar to the Thunderbolt implementation?
Sounds good to me, but I think we should split up the UCSI_MAX_ALTMODES check and the port_altmode check. Returning EBUSY doesn't seem like an appropriate error code if the PPM returns an out of range option. I think we should return EINVAL here.