summaryrefslogtreecommitdiff
path: root/driver/nfc
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2021-04-10 08:22:05 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-28 17:39:35 +0000
commit8fb365850415a44c7f8eeaba154381cdb82a6493 (patch)
treec68b73a86d7ef1913bdabd620fe739380ac513e5 /driver/nfc
parent5dfaf9e91b27fb91b58725ffdf96cf861a75011b (diff)
downloadchrome-ec-8fb365850415a44c7f8eeaba154381cdb82a6493.tar.gz
ctn730: Handle messages with no payload properly
Messages without payload are allowed in the specification though they're currently not used in the implementation. This patch makes ctn730 driver properly handle such messages. BUG=b:192087974, b:190841496 BRANCH=None TEST=make run-pchg_fuzz Change-Id: I2d53ba3d45eb3684db7777627d392b1c8570b5ca Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2987906 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'driver/nfc')
-rw-r--r--driver/nfc/ctn730.c40
-rw-r--r--driver/nfc/ctn730.h2
2 files changed, 28 insertions, 14 deletions
diff --git a/driver/nfc/ctn730.c b/driver/nfc/ctn730.c
index 657635dd94..6f711c509e 100644
--- a/driver/nfc/ctn730.c
+++ b/driver/nfc/ctn730.c
@@ -248,22 +248,26 @@ static int _process_payload_response(struct pchg *ctx, struct ctn730_msg *res)
{
uint8_t len = res->length;
uint8_t buf[CTN730_MESSAGE_BUFFER_SIZE];
- int rv;
if (sizeof(buf) < len) {
CPRINTS("Response size (%d) exceeds buffer", len);
return EC_ERROR_OVERFLOW;
}
- rv = _i2c_read(ctx->cfg->i2c_port, buf, len);
- if (rv)
- return rv;
-
- if (IS_ENABLED(CTN730_DEBUG))
- CPRINTS("Payload: %ph", HEX_BUF(buf, len));
+ if (len > 0) {
+ int rv = _i2c_read(ctx->cfg->i2c_port, buf, len);
+ if (rv)
+ return rv;
+ if (IS_ENABLED(CTN730_DEBUG))
+ CPRINTS("Payload: %ph", HEX_BUF(buf, len));
+ }
ctx->event = PCHG_EVENT_NONE;
+ /*
+ * Messages with no payload (<len> == 0) is allowed in the spec. So,
+ * make sure <len> is checked before reading buf[0].
+ */
switch (res->instruction) {
case WLC_HOST_CTRL_RESET:
if (len != WLC_HOST_CTRL_RESET_RSP_SIZE)
@@ -345,24 +349,30 @@ static int _process_payload_event(struct pchg *ctx, struct ctn730_msg *res)
{
uint8_t len = res->length;
uint8_t buf[CTN730_MESSAGE_BUFFER_SIZE];
- int rv;
if (sizeof(buf) < len) {
CPRINTS("Response size (%d) exceeds buffer", len);
return EC_ERROR_OVERFLOW;
}
- rv = _i2c_read(ctx->cfg->i2c_port, buf, len);
- if (rv)
- return rv;
-
- if (IS_ENABLED(CTN730_DEBUG))
- CPRINTS("Payload: %ph", HEX_BUF(buf, len));
+ if (len > 0) {
+ int rv = _i2c_read(ctx->cfg->i2c_port, buf, len);
+ if (rv)
+ return rv;
+ if (IS_ENABLED(CTN730_DEBUG))
+ CPRINTS("Payload: %ph", HEX_BUF(buf, len));
+ }
ctx->event = PCHG_EVENT_NONE;
+ /*
+ * Messages with no payload (<len> == 0) is allowed in the spec. So,
+ * make sure <len> is checked before reading buf[0].
+ */
switch (res->instruction) {
case WLC_HOST_CTRL_RESET:
+ if (len < WLC_HOST_CTRL_RESET_EVT_MIN_SIZE)
+ return EC_ERROR_INVAL;
if (buf[0] == WLC_HOST_CTRL_RESET_EVT_NORMAL_MODE) {
if (len != WLC_HOST_CTRL_RESET_EVT_NORMAL_MODE_SIZE)
return EC_ERROR_INVAL;
@@ -392,6 +402,8 @@ static int _process_payload_event(struct pchg *ctx, struct ctn730_msg *res)
ctx->event = PCHG_EVENT_DISABLED;
break;
case WLC_CHG_CTRL_DEVICE_STATE:
+ if (len < WLC_CHG_CTRL_DEVICE_STATE_EVT_SIZE)
+ return EC_ERROR_INVAL;
switch (buf[0]) {
case WLC_CHG_CTRL_DEVICE_STATE_DEVICE_DOCKED:
if (len != WLC_CHG_CTRL_DEVICE_STATE_EVT_SIZE)
diff --git a/driver/nfc/ctn730.h b/driver/nfc/ctn730.h
index 7a243c0561..0195b36a6d 100644
--- a/driver/nfc/ctn730.h
+++ b/driver/nfc/ctn730.h
@@ -45,6 +45,8 @@
#define WLC_HOST_CTRL_RESET_REASON_UNRECOVERABLE 0x02
#define WLC_HOST_CTRL_RESET_CMD_MODE_NORMAL 0x00
#define WLC_HOST_CTRL_RESET_CMD_MODE_DOWNLOAD 0x01
+#define WLC_HOST_CTRL_RESET_EVT_MIN_SIZE \
+ WLC_HOST_CTRL_RESET_EVT_DOWNLOAD_MODE_SIZE
/* WLC_HOST_CTRL_DL_* constants */
#define WLC_HOST_CTRL_DL_OPEN_SESSION_CMD_SIZE 2