diff options
author | Diana Z <dzigterman@chromium.org> | 2018-11-29 10:29:19 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2019-02-07 20:47:36 +0000 |
commit | 5f8c9c45cb6f5be3cd0f11f0e5c2e17605b837df (patch) | |
tree | c1825957371981cba2b21effb429c2cc22e46011 | |
parent | c26996a848d6e2e0e2916e0cbfe716fff532f767 (diff) | |
download | chrome-ec-5f8c9c45cb6f5be3cd0f11f0e5c2e17605b837df.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>
(cherry picked from commit f556c986d1bf6688adceaaeeb18a272a5231b7ec)
Reviewed-on: https://chromium-review.googlesource.com/c/1405395
Commit-Queue: Todd Broch <tbroch@chromium.org>
Tested-by: Todd Broch <tbroch@chromium.org>
-rw-r--r-- | common/usb_pd_policy.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 0d8c6c08c1..93924815a2 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -319,10 +319,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) { @@ -330,6 +331,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) @@ -343,6 +350,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)) @@ -745,7 +753,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: |