summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMuhammad Bilal <meatuni001@gmail.com>2026-05-24 13:03:19 +0000
committerRob Herring (Arm) <robh@kernel.org>2026-06-04 17:43:43 -0500
commitd9d021218162b6c4fe0bdf42b2b340f1aae23a12 (patch)
treeab060e51fd6b1d54e094d809ebe9caaafc3d183b /drivers
parentee6d9b6e51626f259c6f0e38d94f91be4fd14754 (diff)
downloadlwn-d9d021218162b6c4fe0bdf42b2b340f1aae23a12.tar.gz
lwn-d9d021218162b6c4fe0bdf42b2b340f1aae23a12.zip
accel/ethosu: reject DMA commands with uninitialized length
cmd_state_init() initializes the command state with memset(0xff), leaving dma->len at U64_MAX to signal missing setup. The only setter is NPU_SET_DMA0_LEN; if userspace omits this command and issues NPU_OP_DMA_START, dma->len remains U64_MAX. In dma_length(), a positive stride added to U64_MAX wraps to a small value. With size0 == 1, check_mul_overflow() does not trigger and dma_length() returns 0 instead of U64_MAX. The caller's U64_MAX check then passes, region_size[] stays 0, and the bounds check in ethosu_job.c is bypassed, allowing hardware to execute DMA with stale physical addresses. Fix by checking for U64_MAX at the start of dma_length() before any arithmetic, consistent with the sentinel value used throughout the driver to detect uninitialized fields. Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Bilal <meatuni001@gmail.com> Link: https://patch.msgid.link/20260524130319.12747-1-meatuni001@gmail.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accel/ethosu/ethosu_gem.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 27c5fdbe9a5d..2cb7964ddfa5 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -164,6 +164,9 @@ static u64 dma_length(struct ethosu_validated_cmdstream_info *info,
s8 mode = dma_st->mode;
u64 len = dma->len;
+ if (len == U64_MAX)
+ return U64_MAX;
+
if (mode >= 1) {
if (dma->stride[0] < 0 && (u64)(-dma->stride[0]) > len)
return U64_MAX;