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-10 00:25:56 +0000
commitc8a5f1c1693700760559934504617997baf1e654 (patch)
tree4a8642de204c45f171203613b2ef4ddea5092633
parent1fe7f225ccba0d6551c9b2cf27f28a3d3b4324eb (diff)
downloadchrome-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.c18
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)