summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Yilun Lin <yllin@chromium.org>2021-09-14 14:41:18 +0800
committerCommit Bot <commit-bot@chromium.org>2021-09-16 01:44:20 +0000
commitf464d2e99a9cb51cd422d65f43c9a77b57744003 (patch)
tree8cafbfef7ba6469c2927b0c9264e292eede6adc6
parentcef83663e1d7cc296e6e3bfddab410c70c303e54 (diff)
downloadchrome-ec-f464d2e99a9cb51cd422d65f43c9a77b57744003.tar.gz
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 <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3159850 Tested-by: Eric Yilun Lin <yllin@google.com> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Eric Yilun Lin <yllin@google.com>
-rw-r--r--common/usb_pd_dual_role.c8
1 files 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);
}