From 84e85bd6f0143ae1cb801fc56831ef522ba9f6e5 Mon Sep 17 00:00:00 2001 From: Todd Broch Date: Mon, 13 Apr 2015 19:00:01 -0700 Subject: [PATCH] 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 Reviewed-on: https://chromium-review.googlesource.com/265620 Reviewed-by: Alec Berg --- common/usb_pd_policy.c | 24 +++++++++++++++--------- 1 file 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;