In cmd_to_addr(), the expression (cmd[0] & 0xff0000) << 16 performs the left-shift in 32-bit arithmetic because cmd[0] is u32 and the intermediate result of the AND is also u32. The meaningful bits (positions 16-23) need to land in positions 32-39 of the result, but these positions exceed the 32-bit width, so they are silently discarded before the cast to u64.
This causes cmd_to_addr() to always return an address with a zeroed upper half, producing an incorrect DMA address for the Ethos-U NPU. The device may then read from or write to the wrong physical memory region, leading to kernel memory corruption or information disclosure. Fix by casting to u64 before the shift so the operation is performed in 64-bit arithmetic and no bits are lost. Found by manual source code audit of Linux kernel v6.19 (drivers/accel/ethosu/ethosu_gem.c, line 157). Affected versions: v6.19+ (since initial Ethos-U driver merge). Signed-off-by: Dhabaleshwar Das ([email protected]) --- drivers/accel/ethosu/ethosu_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c index abcdef1..1234567 100644 --- a/drivers/accel/ethosu/ethosu_gem.c +++ b/drivers/accel/ethosu/ethosu_gem.c @@ -155,7 +155,7 @@ static u64 cmd_to_addr(u32 *cmd) static u64 cmd_to_addr(u32 *cmd) { - return ((u64)((cmd[0] & 0xff0000) << 16)) | cmd[1]; + return (((u64)(cmd[0] & 0xff0000)) << 16) | cmd[1]; }
