diff options
author | Caveh Jalali <caveh@chromium.org> | 2019-10-04 21:41:58 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-10 00:25:56 +0000 |
commit | c8a5f1c1693700760559934504617997baf1e654 (patch) | |
tree | 4a8642de204c45f171203613b2ef4ddea5092633 | |
parent | 1fe7f225ccba0d6551c9b2cf27f28a3d3b4324eb (diff) | |
download | chrome-ec-c8a5f1c1693700760559934504617997baf1e654.tar.gz |
tcpci: protect against buffer overflow
we need to sanity check data read from TCPCs to avoid buffer
overflows. the TCPC can return bogus size information which can cause
a buffer overflow when processing TCPM messages. if the claimed
message size is bogus, return an error.
BUG=b:142296767
BRANCH=none
TEST=EC no longer gets an exception
Change-Id: I7754c6e3d20847827b849423c5880756bae46393
Signed-off-by: Caveh Jalali <caveh@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1845586
Reviewed-by: Caveh Jalali <caveh@google.com>
Commit-Queue: Caveh Jalali <caveh@google.com>
-rw-r--r-- | driver/tcpm/tcpci.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index 51ddcb5901..5262a384c0 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -7,6 +7,7 @@ #include "atomic.h" #include "anx74xx.h" +#include "compile_time_macros.h" #include "console.h" #include "ec_commands.h" #include "ps8xxx.h" @@ -373,6 +374,11 @@ int tcpci_tcpm_get_vbus_level(int port) } #endif +struct cached_tcpm_message { + uint32_t header; + uint32_t payload[7]; +}; + int tcpci_tcpm_get_message_raw(int port, uint32_t *payload, int *head) { int rv, cnt, reg = TCPC_REG_RX_DATA; @@ -387,6 +393,12 @@ int tcpci_tcpm_get_message_raw(int port, uint32_t *payload, int *head) rv = EC_ERROR_UNKNOWN; goto clear; } + cnt -= 3; + if (cnt > member_size(struct cached_tcpm_message, payload)) { + rv = EC_ERROR_UNKNOWN; + goto clear; + } + #ifdef CONFIG_USB_PD_DECODE_SOP rv = tcpc_read(port, TCPC_REG_RX_BUF_FRAME_TYPE, &frm); if (rv != EC_SUCCESS) { @@ -402,7 +414,6 @@ int tcpci_tcpm_get_message_raw(int port, uint32_t *payload, int *head) *head &= 0x0000ffff; *head |= PD_HEADER_SOP(frm & 7); #endif - cnt = cnt - 3; if (rv == EC_SUCCESS && cnt > 0) { tcpc_read_block(port, reg, (uint8_t *)payload, cnt); } @@ -414,11 +425,6 @@ clear: return rv; } -struct cached_tcpm_message { - uint32_t header; - uint32_t payload[7]; -}; - /* Cache depth needs to be power of 2 */ #define CACHE_DEPTH (1 << 2) #define CACHE_DEPTH_MASK (CACHE_DEPTH - 1) |