{"id":"CVE-2026-99184","kind":"vulnerability","aliases":["CVE-2026-99184"],"related":[],"title":"Linux kernel: Rockchip NPU driver overruns core array on unbind and rebind","description":"In the Linux kernel, the following vulnerability has been resolved:\n\naccel/rocket: search every core slot when a core is removed\n\nrocket_remove() decrements rdev->num_cores for each core it removes,\nwhile find_core_for_dev() searches slots 0 to num_cores - 1. Unbinding\nthe cores in the order they were bound therefore loses the last one: by\nthe time it is removed the search range has already shrunk past its\nslot, so find_core_for_dev() returns -1 and rocket_remove() gives up\nwithout doing anything.\n\nnum_cores never reaches zero, rocket_device_fini() never runs, and the\nfile-scoped rdev keeps pointing at a device that is going away. Binding\nthe cores again starts from that stale count, because rocket_probe()\ntakes rdev->num_cores as the slot to fill. On an RK3588, which describes\nthree cores, the second round lands on slots 1, 2 and 3 while rdev->cores\nwas allocated with room for three:\n\n  rocket fdab0000.npu: Rockchip NPU core 1 version: 1179210309\n  rocket fdac0000.npu: Rockchip NPU core 2 version: 1179210309\n  rocket fdad0000.npu: Rockchip NPU core 3 version: 1179210309\n\nThe write to rdev->cores[3] is past the end of the array.\n\nNothing in tree reads the core array often enough to notice, so the\noverrun is silent today. It turned up while testing a devfreq series on\ntop of this, where a worker walks every core a few times a second, and\nUBSAN caught the first bool it read out of the overrun entry:\n\n  UBSAN: invalid-load in drivers/accel/rocket/rocket_devfreq.c:47:10\n  load of value 5 is not a valid value for type '_Bool'\n  Workqueue: devfreq_wq devfreq_monitor\n\nRecord how many slots were allocated and search all of them. Every core\nis then found on removal, num_cores reaches zero, the device is torn down\nand a later bind starts from a clean rdev.\n\nThis does not make unbinding a single core out of several work. probe\nstill takes num_cores as the slot to fill, so rebinding one core while\nits siblings stay bound would write over a slot that is already in use,\nand rocket_open() still reaches for cores[0] whether or not anything is\nthere. Both of those want more thought than a fix should carry.\n\nFound by unbinding and rebinding all three cores on an Orange Pi 5 Plus.\nWith this applied, 25 unbind/rebind rounds and 5 module unload/reload\nrounds run clean there: the cores land in slots 0, 1 and 2 every time,\nwhichever order they are bound in, and the shared supply goes back to a\nsingle user after each round.","summary":"The Linux kernel accel/rocket driver for Rockchip NPUs loses track of the last core when cores are unbound, so a rebind writes past the end of the rdev->cores array. The sources describe a silent out-of-bounds write and a UBSAN-reported invalid bool load, with no confirmed attacker capability.","severity":"unknown","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["arm","embedded","infrastructure","linux-kernel","rk3588","rockchip"],"not_affected_if":["no-core-unbind","no-rockchip-npu"],"how_to_check":"- `uname -r` to see the running kernel version\n- Check whether the `rocket` module is loaded with `lsmod | grep rocket`\n- Check for Rockchip NPU devices bound to the driver under `/sys/bus/platform/drivers/rocket/`","fix":"- Update the Linux kernel to a release that includes the upstream commit titled 'accel/rocket: search every core slot when a core is removed'\n- Until patched, avoid unbinding individual NPU cores on affected systems (unknown exact fixed version)","status":"open","published_at":"2026-10-28T11:17:39+00:00","first_seen_at":"2026-10-28T11:32:37+00:00","triaged_at":"2026-10-28T11:35:20+00:00","updated_at":"2026-10-28T11:35:20+00:00","category":"infrastructure","confidence":0.5,"triage":{"at":"2026-10-28T11:35:20Z","model":"claude-haiku-5-5","output":{"fix":"- Update the Linux kernel to a release that includes the upstream commit titled 'accel/rocket: search every core slot when a core is removed'\n- Until patched, avoid unbinding individual NPU cores on affected systems (unknown exact fixed version)","reach":"local","title":"Linux kernel: Rockchip NPU driver overruns core array on unbind and rebind","impact":"medium","summary":"The Linux kernel accel/rocket driver for Rockchip NPUs loses track of the last core when cores are unbound, so a rebind writes past the end of the rdev->cores array. The sources describe a silent out-of-bounds write and a UBSAN-reported invalid bool load, with no confirmed attacker capability.","category":"infrastructure","nicknames":[],"who_cares":["linux-kernel","rockchip","rk3588","embedded","arm"],"confidence":0.5,"needs_auth":"unknown","worst_case":"out-of-bounds kernel memory write during NPU core rebind","analyst_note":"Check the NVD entry and the upstream kernel commit for the fixed kernel versions and whether any exploitation path beyond local unbind/rebind exists.","how_to_check":"- `uname -r` to see the running kernel version\n- Check whether the `rocket` module is loaded with `lsmod | grep rocket`\n- Check for Rockchip NPU devices bound to the driver under `/sys/bus/platform/drivers/rocket/`","needs_analyst":true,"not_affected_if":["no-rockchip-npu","no-core-unbind"],"who_is_affected":"Systems running a Linux kernel with the accel/rocket driver for Rockchip NPUs, such as RK3588 boards like the Orange Pi 5 Plus. The bug triggers when cores are unbound and rebound, so the risk is limited to hosts that do that. Teams not using Rockchip NPU hardware can skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.000758,"input_tokens":4107,"output_tokens":694,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'-1':158C '-2026':14A,17A '-99184':15A,18A '0':118C,438C,489C '1':122C,226C,244C,490C '10':336C '1179210309':246C,254C,262C '2':227C,252C,492C '25':473C '3':229C,260C,268C '47':335C '5':340C,468C,477C 'accel/rocket':30B,90C 'alloc':234C,359C 'alreadi':147C,428C 'anyth':166C,442C 'appli':472C 'arm':19B 'array':8A,56B,275C,282C 'attack':78B 'away':191C 'back':506C 'bind':192C,384C 'bool':73B,321C,348C 'bound':65B,131C,420C,499C 'capabl':79B 'carri':455C 'caught':318C 'clean':388C,482C 'confirm':77B 'core':7A,40B,42B,55B,93C,97C,105C,108C,113C,121C,125C,154C,168C,194C,207C,219C,232C,243C,251C,259C,267C,281C,310C,366C,373C,397C,406C,415C,437C,463C,485C 'count':200C 'cve':13A,16A 'decrement':102C 'describ':59B,217C 'dev':115C,156C 'devfreq':299C,350C,352C 'devic':173C,187C,377C 'driver':5A,31B 'drivers/accel/rocket/rocket_devfreq.c':334C 'embed':20B 'end':51B,272C 'enough':284C 'entri':328C 'everi':92C,309C,365C,493C 'fdab0000.npu':240C 'fdac0000.npu':248C 'fdad0000.npu':256C 'file':180C 'file-scop':179C 'fill':212C,411C 'find':112C,153C 'fini':174C 'first':320C 'fix':453C 'follow':85C 'found':369C,456C 'give':162C 'go':190C 'goe':505C 'infrastructur':21B 'invalid':72B,331C 'invalid-load':330C 'keep':183C 'kernel':2A,24B,29B,83C 'land':223C,486C 'last':39B,135C 'later':383C 'linux':1A,23B,28B,82C 'linux-kernel':22B 'load':74B,332C,337C 'lose':35B,133C 'make':393C 'mani':356C 'modul':478C 'monitor':353C 'never':169C,175C 'noth':276C 'notic':286C 'npu':4A,242C,250C,258C 'npus':34B 'num':104C,120C,167C,206C,372C,405C 'often':283C 'one':136C,414C 'open':433C 'orang':466C 'order':128C,496C 'out-of-bound':62B 'overrun':6A,289C,327C 'past':49B,149C,270C 'pi':467C 'plus':469C 'point':184C 'probe':203C,402C 'rang':145C 'rdev':54B,103C,182C,205C,231C,266C,389C 'reach':170C,374C,435C 'read':279C,323C 'rebind':12A,47B,413C,460C 'record':354C 'remov':99C,101C,110C,142C,161C,371C 'report':71B 'resolv':89C 'return':157C 'rk3588':25B,215C 'rockchip':3A,26B,33B,241C,249C,257C 'rocket':100C,160C,172C,202C,239C,247C,255C,432C 'room':236C 'round':222C,475C,480C,513C 'run':176C,481C 'scope':181C 'search':91C,116C,144C,361C 'second':221C,315C 'seri':300C 'sever':400C 'share':503C 'shrunk':148C 'sibl':418C 'silent':61B,291C 'singl':396C,509C 'slot':94C,117C,151C,210C,225C,357C,409C,425C,488C 'sourc':58B 'stale':199C 'start':196C,385C 'stay':419C 'still':403C,434C 'suppli':504C 'take':204C,404C 'test':297C 'therefor':132C 'thought':450C 'three':218C,238C,462C 'time':139C,313C,494C 'today':292C 'top':302C 'torn':379C 'track':36B 'tree':278C 'turn':294C 'type':347C 'ubsan':70B,317C,329C 'ubsan-report':69B 'unbind':10A,123C,394C,458C 'unbind/rebind':474C 'unbound':44B 'unload/reload':479C 'use':430C 'user':510C 'valid':344C 'valu':339C,345C 'version':245C,253C,261C 'vulner':86C 'walk':308C 'want':448C 'whether':439C 'whichev':495C 'without':164C 'work':401C 'worker':307C 'workqueu':349C 'would':421C 'wq':351C 'write':48B,66B,264C,422C 'zero':171C,375C","nicknames":[],"mitigations":[],"who_affected":"Systems running a Linux kernel with the accel/rocket driver for Rockchip NPUs, such as RK3588 boards like the Orange Pi 5 Plus. The bug triggers when cores are unbound and rebound, so the risk is limited to hosts that do that. Teams not using Rockchip NPU hardware can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-28T11:17:39+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-99184","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99184","severity":null,"published_at":"2026-10-28T11:17:39+00:00","modified_at":"2026-10-28T11:17:39+00:00","first_seen_at":"2026-10-28T11:32:37+00:00","fetched_at":"2026-10-28T11:32:37+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}