summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2015-04-13 19:00:01 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-04-14 17:56:08 +0000
commit84e85bd6f0143ae1cb801fc56831ef522ba9f6e5 (patch)
tree1aa581267be0159a7eee2f84e1aacb0add1e2095
parent3779b8ccbebf19155f98c924bfa39acf6ecc317f (diff)
downloadchrome-ec-84e85bd6f0143ae1cb801fc56831ef522ba9f6e5.tar.gz
pd: Qualify modep pointer before use.
If UFP sends invalid VDM responses to the DFP its possible that modep pointer may be NULL. CL qualifies all uses of modep to guarantee that these invalid responses don't cause samus_pd to crash. BRANCH=samus BUG=chromium:476773 TEST=manual, 1. Still successfully negotiate alternate mode (both DP & GFU) with hoho. 2. passes usbpd_DisplayPortSink autotest. Change-Id: If4a611182b5e659c5534c2206132ef76d4e023db Signed-off-by: Todd Broch <tbroch@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/265620 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--common/usb_pd_policy.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index 3a620eb1f1..b5d6f91b91 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -399,7 +399,7 @@ static void dfp_consume_attention(int port, uint32_t *payload)
int opos = PD_VDO_OPOS(payload[0]);
struct svdm_amode_data *modep = get_modep(port, svid);
- if (!validate_mode_request(modep, svid, opos))
+ if (!modep || !validate_mode_request(modep, svid, opos))
return;
if (modep->fx->attention)
@@ -432,7 +432,7 @@ int pd_dfp_exit_mode(int port, uint16_t svid, int opos)
* multiple modes on one SVID.
*/
modep = get_modep(port, svid);
- if (!validate_mode_request(modep, svid, opos))
+ if (!modep || !validate_mode_request(modep, svid, opos))
return 0;
/* call DFPs exit function */
@@ -610,24 +610,30 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
}
break;
case CMD_ENTER_MODE:
- if (!modep->opos)
- pd_dfp_enter_mode(port, 0, 0);
- if (modep->opos) {
- rsize = modep->fx->status(port, payload);
- payload[0] |= PD_VDO_OPOS(modep->opos);
+ if (!modep) {
+ rsize = 0;
+ } else {
+ if (!modep->opos)
+ pd_dfp_enter_mode(port, 0, 0);
+
+ if (modep->opos) {
+ rsize = modep->fx->status(port,
+ payload);
+ payload[0] |= PD_VDO_OPOS(modep->opos);
+ }
}
break;
case CMD_DP_STATUS:
/* DP status response & UFP's DP attention have same
payload */
dfp_consume_attention(port, payload);
- if (modep->opos)
+ if (modep && modep->opos)
rsize = modep->fx->config(port, payload);
else
rsize = 0;
break;
case CMD_DP_CONFIG:
- if (modep->opos && modep->fx->post_config)
+ if (modep && modep->opos && modep->fx->post_config)
modep->fx->post_config(port);
/* no response after DFPs ack */
rsize = 0;