summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2018-11-29 10:29:19 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-12-03 12:43:35 -0800
commitf556c986d1bf6688adceaaeeb18a272a5231b7ec (patch)
treef714a38261518538cef2a7b9c1e9edb99cf84bba
parent90db0f71af1f906a50b90391537410b149cfca3f (diff)
downloadchrome-ec-f556c986d1bf6688adceaaeeb18a272a5231b7ec.tar.gz
PD: Ensure SVID parsing doesn't exceed packet boundaries
When responding to DiscSVID requests, most port partners will include an SVID value of 0 to indicate the end of the SVIDs. However, not all dongles follow this rule and their packet may end with a VDO containing two non-zero SVIDs. In this scenario, we should stop parsing when we reach the end of the valid packet region to avoid finding junk SVIDs. BRANCH=coral,eve,fizz,glados,gru,grunt,nami,nocturne,oak,octopus,poppy, reef,samus,scarlet,smaug BUG=b:116764439 TEST=on bobba360, verified there were no regressions in SVID parsing with well-behaving dongles (hoho - 2 VDOs, apple - 2 VDOs, DA200 - 1VDO, 7magic - 1 VDO) Change-Id: Id2b40ba918439aeb214efb43837dd995ff0b9d86 Signed-off-by: Diana Z <dzigterman@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1355364 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r--common/usb_pd_policy.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 9d2b374259..25949289ee 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -315,10 +315,11 @@ static int dfp_discover_svids(int port, uint32_t *payload)
return 1;
}
-static void dfp_consume_svids(int port, uint32_t *payload)
+static void dfp_consume_svids(int port, int cnt, uint32_t *payload)
{
int i;
uint32_t *ptr = payload + 1;
+ int vdo = 1;
uint16_t svid0, svid1;
for (i = pe[port].svid_cnt; i < pe[port].svid_cnt + 12; i += 2) {
@@ -326,6 +327,12 @@ static void dfp_consume_svids(int port, uint32_t *payload)
CPRINTF("ERR:SVIDCNT\n");
break;
}
+ /*
+ * Verify we're still within the valid packet (count will be one
+ * for the VDM header + xVDOs)
+ */
+ if (vdo >= cnt)
+ break;
svid0 = PD_VDO_SVID_SVID0(*ptr);
if (!svid0)
@@ -339,6 +346,7 @@ static void dfp_consume_svids(int port, uint32_t *payload)
pe[port].svids[i + 1].svid = svid1;
pe[port].svid_cnt++;
ptr++;
+ vdo++;
}
/* TODO(tbroch) need to re-issue discover svids if > 12 */
if (i && ((i % 12) == 0))
@@ -741,7 +749,7 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
#endif
break;
case CMD_DISCOVER_SVID:
- dfp_consume_svids(port, payload);
+ dfp_consume_svids(port, cnt, payload);
rsize = dfp_discover_modes(port, payload);
break;
case CMD_DISCOVER_MODES: