ANDROID: usb: typec: ucsi: Ensure bounds check when accessing src_pdos

Currently, when reading the following properties under
ucsi-source-psy-*, src_pdos array is accessed but it only checks
for the condition num_pdos > 0.

- voltage_max
- voltage_now
- current_max

In the case if a PPM passes num_pdos greater than UCSI_MAX_PDOS,
an OOB access can be made. Fix it by checking the upper bound for
src_pdos which is UCSI_MAX_PDOS.

This issue is detected by enabling UBSAN.

Bug: 186400956
Fixes: 992a60ed0d ("usb: typec: ucsi: register with power_supply class")
Fixes: 4dbc6a4ef0 ("usb: typec: ucsi: save power data objects in PD mode")
Change-Id: Id0aca674208b23329be089671cba873baca930cf
Signed-off-by: Subbaraman Narayanamurthy <quic_subbaram@quicinc.com>
This commit is contained in:
Subbaraman Narayanamurthy 2021-05-10 10:31:41 -07:00 committed by Greg Kroah-Hartman
commit cd04f7fab9

View file

@ -69,7 +69,7 @@ static int ucsi_psy_get_voltage_max(struct ucsi_connector *con,
switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
if (con->num_pdos > 0) {
if (con->num_pdos > 0 && con->num_pdos <= UCSI_MAX_PDOS) {
pdo = con->src_pdos[con->num_pdos - 1];
val->intval = pdo_fixed_voltage(pdo) * 1000;
} else {
@ -98,7 +98,7 @@ static int ucsi_psy_get_voltage_now(struct ucsi_connector *con,
switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
index = rdo_index(con->rdo);
if (index > 0) {
if (index > 0 && index <= UCSI_MAX_PDOS) {
pdo = con->src_pdos[index - 1];
val->intval = pdo_fixed_voltage(pdo) * 1000;
} else {
@ -125,7 +125,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con,
switch (UCSI_CONSTAT_PWR_OPMODE(con->status.flags)) {
case UCSI_CONSTAT_PWR_OPMODE_PD:
if (con->num_pdos > 0) {
if (con->num_pdos > 0 && con->num_pdos <= UCSI_MAX_PDOS) {
pdo = con->src_pdos[con->num_pdos - 1];
val->intval = pdo_max_current(pdo) * 1000;
} else {