summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaveh Jalali <caveh@chromium.org>2019-10-04 21:41:58 -0700
committerCommit Bot <commit-bot@chromium.org>2019-10-11 06:28:09 +0000
commit2461586d902615cf53f335c7d9ba161533dde4b8 (patch)
treee8f7bf90c533c1d39e36d7fedf2c6ad8a1fcd5e0
parentb9f24d30e9a379f1ab8d457e655b3e22301dd4ca (diff)
downloadchrome-ec-2461586d902615cf53f335c7d9ba161533dde4b8.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/+/1845587 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Caveh Jalali <caveh@google.com>
-rw-r--r--driver/tcpm/tcpci.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 9ceb4613e2..cc4a0341eb 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"
@@ -414,6 +415,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;
@@ -428,6 +434,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) {
@@ -443,7 +455,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);
}
@@ -455,11 +466,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 BIT(2)
#define CACHE_DEPTH_MASK (CACHE_DEPTH - 1)