|
From: openocd-gerrit <ope...@us...> - 2026-09-08 08:15:16
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 8a6cf324c618c7bccc7cb61f7e533d69022e6e97 (commit)
from 71576b70c75d17dc7b613a310b7797cd9b5dcfaa (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 8a6cf324c618c7bccc7cb61f7e533d69022e6e97
Author: Tomas Vanek <va...@fb...>
Date: Fri Aug 21 11:00:29 2026 +0200
jtag/drivers/cmsis_dap: add SWD transfer response size checks
First check if the adapter response is long enough to parse the header
safely. Then check response size during parsing DP/AP read response data.
Change-Id: I60d08e97d2458c375db97a83d319ef90a6978190
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9858
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index d3f32c98c..fda8d68e5 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -908,6 +908,34 @@ skip:
block->transfer_count = 0;
}
+static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count,
+ unsigned int read_count, bool block_tfer)
+{
+ unsigned int size;
+ if (block_tfer) {
+ size = 5; /* DAP_TransferBlock header */
+ size += write_count * 4; /* data */
+ } else {
+ size = 3; /* DAP_Transfer header */
+ size += write_count * (1 + 4); /* DAP register + data */
+ size += read_count; /* DAP register */
+ }
+ return size;
+}
+
+static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count,
+ unsigned int read_count, bool block_tfer)
+{
+ unsigned int size;
+ if (block_tfer)
+ size = 4; /* DAP_TransferBlock response header */
+ else
+ size = 3; /* DAP_Transfer response header */
+
+ size += read_count * 4; /* data */
+ return size;
+}
+
static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blocking blocking)
{
int retval;
@@ -951,13 +979,24 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
uint8_t *resp = dap->response;
if (resp[0] != block->command) {
- LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8,
- block->command, resp[0]);
+ LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%" PRIx8
+ " received 0x%" PRIx8, block->command, resp[0]);
cmsis_dap_swd_cancel_transfers(dap);
queued_retval = ERROR_FAIL;
return;
}
+ unsigned int resp_size = retval;
+ bool block_cmd = (block->command == CMD_DAP_TFER_BLOCK);
+ unsigned int expect_hdr_size = cmsis_dap_tfer_resp_size(0, 0, block_cmd);
+ if (resp_size < expect_hdr_size) {
+ LOG_ERROR("CMSIS-DAP too short response: expected header %u, got %u",
+ expect_hdr_size, resp_size);
+ cmsis_dap_swd_cancel_transfers(dap);
+ queued_retval = ERROR_JTAG_DEVICE_ERROR;
+ return;
+ }
+
unsigned int transfer_count;
unsigned int idx;
if (block->command == CMD_DAP_TFER_BLOCK) {
@@ -997,6 +1036,13 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
struct pending_transfer_result *transfer = &(block->transfers[i]);
if (transfer->cmd & SWD_CMD_RNW) {
static uint32_t last_read;
+ if (idx + 4 > resp_size) {
+ LOG_ERROR("CMSIS-DAP too short response: expected at least %u, got %u",
+ idx + 4, resp_size);
+ cmsis_dap_swd_cancel_transfers(dap);
+ queued_retval = ERROR_JTAG_DEVICE_ERROR;
+ return;
+ }
uint32_t data = le_to_h_u32(&resp[idx]);
uint32_t tmp = data;
idx += 4;
@@ -1043,34 +1089,6 @@ static int cmsis_dap_swd_run_queue(void)
return retval;
}
-static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count,
- unsigned int read_count, bool block_tfer)
-{
- unsigned int size;
- if (block_tfer) {
- size = 5; /* DAP_TransferBlock header */
- size += write_count * 4; /* data */
- } else {
- size = 3; /* DAP_Transfer header */
- size += write_count * (1 + 4); /* DAP register + data */
- size += read_count; /* DAP register */
- }
- return size;
-}
-
-static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count,
- unsigned int read_count, bool block_tfer)
-{
- unsigned int size;
- if (block_tfer)
- size = 4; /* DAP_TransferBlock response header */
- else
- size = 3; /* DAP_Transfer response header */
-
- size += read_count * 4; /* data */
- return size;
-}
-
static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
{
/* TARGETSEL register write cannot be queued */
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 78 +++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 30 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|