From f464d2e99a9cb51cd422d65f43c9a77b57744003 Mon Sep 17 00:00:00 2001 From: Eric Yilun Lin Date: Tue, 14 Sep 2021 14:41:18 +0800 Subject: usb_pd_dual_role: fix dbz when parsing PDO This path was hitted by ec_usb_pd_fuzzer. BUG=b:198325864 TEST=cros_fuzz --board=amd64-generic reproduce \ --fuzzer ec_usb_pd_fuzzer \ --testcase /build/amd64-generic/tmp/\ clusterfuzz-testcase-minimized-ec_usb_pd_fuzzer-6223286274490368 \ --package chromeos-ec --build-type ubsanh BRANCH=main Change-Id: I9575a890bba16145f3d92d1ecc84afcf12d72d67 Signed-off-by: Eric Yilun Lin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3159850 Tested-by: Eric Yilun Lin Reviewed-by: Daisuke Nojiri Commit-Queue: Eric Yilun Lin --- common/usb_pd_dual_role.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/usb_pd_dual_role.c b/common/usb_pd_dual_role.c index 3981353101..52042c5439 100644 --- a/common/usb_pd_dual_role.c +++ b/common/usb_pd_dual_role.c @@ -15,6 +15,9 @@ #define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +/* The macro is used to prevent a DBZ exception while decoding PDOs. */ +#define PROCESS_ZERO_DIVISOR(x) ((x) == 0 ? 1 : (x)) + #if defined(PD_MAX_VOLTAGE_MV) && defined(PD_OPERATING_POWER_MW) /* * As a sink, this is the max voltage (in millivolts) we can request @@ -192,9 +195,10 @@ void pd_extract_pdo_power(uint32_t pdo, uint32_t *ma, uint32_t *max_mv, max_ma = PDO_VAR_MAX_CURRENT(pdo); } else { mw = PDO_BATT_MAX_POWER(pdo); - max_ma = 1000 * mw / *min_mv; + max_ma = 1000 * mw / PROCESS_ZERO_DIVISOR(*min_mv); } - max_ma = MIN(max_ma, PD_MAX_POWER_MW * 1000 / *min_mv); + max_ma = MIN(max_ma, + PD_MAX_POWER_MW * 1000 / PROCESS_ZERO_DIVISOR(*min_mv)); *ma = MIN(max_ma, PD_MAX_CURRENT_MA); } -- cgit v1.2.1