Spectra Assure Free Trial
Get your 14-day free trial of Spectra Assure for Software Supply Chain Security
Get Free TrialMore about Spectra Assure Free Trial
ITScape (CVE-2026-46316) is a guest-to-host escape vulnerability in the vGIC-ITS (Interrupt Translation Service) emulation within KVM/arm64, disclosed by researcher Hyunwoo Kim (V4bel) via oss-security on June 10. The root cause is a race condition in the vgic_its_invalidate_cache() function that produces a double-put use-after-free, ultimately enabling host kernel code execution.
Because the bug lives entirely within in-kernel KVM rather than QEMU user-space, successful exploitation yields host kernel privilege rather than user-process compromise, making it a direct threat to multi-tenant arm64 cloud environments that accept untrusted guests.
In scenarios where the attacker lacks guest root, ITScape can be chained with a local privilege escalation. The vulnerability affects kernels from commit 8201d1028caa (2024-04-25) through 13031fb6b835 (2026-06-05), at which point the patch landed in mainline.
Here’s what you need to know about ITScape — including recommendations for discovery, how to detect exploits with YARA rules, and Indicators of Compromise (IoCs).
Two YARA rules have been developed to detect this threat. ITScape_ExploitConstants_1 targets nine hardcoded 64-bit constants present in the PoC source: kernel symbol addresses (ORDERLY_POWEROFF, POWEROFF_CMD, NEIGH_GC_WORK_FUNC, PMU_FN_LINKED, gadget_rt), an anti-leak sentinel (LEAKLEAD), and the three packed u64 values that compose the /bin/touch /ITScape host command string. All constants are encoded little-endian as they appear in a compiled ARM64 ELF.
Testing against the known PoC binary confirms seven of nine strings match; $pmu_fn_linked and $gadget_rt are absent from this build, most likely because gadget_rt is only ever materialized at runtime as base + voff and the linker does not emit either constant as a bare relocatable literal in this particular build. Both strings are retained in the rule defensively: a statically linked build, a differently optimized build, or a future variant may resolve these constants differently and produce hits where the known sample does not. The constants as found in the poc.c source code are shown in the figures below.

Figure 1: First set of constants defined in the exploit poc.c

Figure 2: Second set of constants
ITScape_KVM_PrivDrop_1 takes a behavioral approach, targeting a semantically unique instruction sequence in the compiled binary: a stat(2) group permission check (st_mode & 0x6 == 0x6) on /dev/kvm followed immediately by setgroups(0, NULL) / setgid(1000) / setuid(1000) with error-checked cbnz branches after each call. Branch offsets and stack frame offsets are wildcarded at the byte and nibble level using ARM64 instruction encoding semantics, making the pattern robust to recompilation while keeping all semantically meaningful immediates as exact matches. The region of disassembled code detected by this rule is shown in the next figure.

Figure 3: Privilege drop on /dev/kvm
Defenders running arm64 KVM hosts should prioritize applying the mainline patch at commit 13031fb6b835 and the two companion fixes for CVE-2026-46316. Organizations operating multi-tenant arm64 infrastructure, particularly public cloud providers, should closely evaluate this issue given that exploitation requires only guest kernel privilege and yields host root. Since this represents a new vulnerability class, additional variants and follow-up vulnerabilities are expected, so continued monitoring of the vgic-its code path is warranted even after patching.
e0ab84da2d2783c8cae3624e8ce58b99ad79219753b249671ff7f743abdacc35rule ITScape_ExploitConstants_1
{
meta:
author = "Malware Utkonos"
date = "2026-05-11"
description = "Detects constants used in ITScape exploit PoC."
reference = "https://github.com/V4bel/ITScape/blob/main/poc.c"
poc = "e0ab84da2d2783c8cae3624e8ce58b99ad79219753b249671ff7f743abdacc35"
strings:
$orderly_poweroff = { 2cf90d800080ffff }
$poweroff_cmd = { c803d0820080ffff }
$neigh_gc_work_func = { 502d1d830080ffff }
$pmu_fn_linked = { b80e09800080ffff }
$gadget_rt = { dcc6d7800080ffff }
// canary magic ("LEAKLEAD" = 0x4c45414b4c454144 byte-swapped)
$leak_sentinel = { 4441454c4b41454c }
// payload: "/bin/touch /ITScape" packed as three u64s
$sc_write_bin_tou = { 2f62696e2f746f75 } // /bin/tou
$sc_write_ch_ITSc = { 6368202f49545363 } // ch /ITSc
$sc_write_ape = { 6170650000000000 } // ape\0
condition:
5 of them
}
rule ITScape_KVM_PrivDrop_1
{
meta:
author = "Malware Utkonos"
date = "2026-05-11"
description = "Detects /dev/kvm group rw check and drop to setgroups/setgid/setuid(1000) used in ITScape PoC."
reference = "https://github.com/V4bel/ITScape/blob/main/poc.c"
poc = "e0ab84da2d2783c8cae3624e8ce58b99ad79219753b249671ff7f743abdacc35"
strings:
$kvm = "/dev/kvm"
$op = { e0??4?b9 00041f12 1f180071 ?1[2]54 010080d2 000080d2 [3]9? 007d8052 [3]9? ?0[2]35 007d8052 [3]9? ?0[2]35 }
// 004025cc e0c340b9 ldr w0, [sp, #0xc0 {guest_memfd.reserved[0].d}] // load stat st_mode; offset floats
// 004025d0 00041f12 and w0, w0, #0x6 // mask S_IRGRP|S_IWGRP (0x4|0x2)
// 004025d4 1f180071 cmp w0, #0x6 // both group rw bits must be set
// 004025d8 c1f0ff54 b.ne 0x4023f0
// 004025dc 010080d2 mov x1, #0 // setgroups(0, NULL)
// 004025e0 000080d2 mov x0, #0
// 004025e4 b3feff97 bl setgroups
// 004025e8 007d8052 mov w0, #0x3e8 // setgid(1000)
// 004025ec 71feff97 bl setgid
// 004025f0 00f0ff35 cbnz w0, 0x4023f0
// 004025f4 007d8052 mov w0, #0x3e8 // setuid(1000)
// 004025f8 a6fdff97 bl setuid
// 004025fc a0efff35 cbnz w0, 0x4023f0
condition:
$kvm and $op
}This post was assembled with assistance from generative AI.