{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-72112","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2026-08-09T03:40:39.906Z","datePublished":"2026-08-15T05:52:53.275Z","dateUpdated":"2026-08-17T05:40:26.740Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2026-08-17T05:40:26.740Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/bpf-ops: reject re-registration of an already-bound ops\n\nio_install_bpf() only rejects a second registration on the ctx side\n(ctx->bpf_ops) and sets the per-map back-pointer ops->priv\nunconditionally. The struct_ops link path never advances a map past\nBPF_STRUCT_OPS_STATE_READY, so the same io_uring_bpf_ops map can be\nregistered more than once, and bpf_io_reg() re-resolves the target ring\nvia fget(ops->ring_fd) on every call. A caller can therefore point the\nsame ring_fd at a different io_ring_ctx between two BPF_LINK_CREATE\ncalls.\n\nThe second registration passes the ctx->bpf_ops check (the new ctx has\nnone) and overwrites ops->priv, orphaning the first ctx. Teardown\n(io_eject_bpf()/bpf_io_unreg()) only reaches a ctx through ops->priv, so\nthe orphaned ctx is never torn down: its ctx->loop_step keeps pointing\ninto the struct_ops trampoline, which is freed once the map is gone. A\nlater io_uring_enter() on the orphaned ring then calls the dangling\nctx->loop_step from io_run_loop() -- a use-after-free of freed\nexecutable memory, reachable by a task with CAP_BPF + CAP_PERFMON.\n\nReject registration when ops->priv is already set, as hid_bpf_reg()\ndoes for its struct_ops."}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - The bug is reached only through local bpf() syscalls (BPF_MAP_CREATE/UPDATE_ELEM, BPF_PROG_LOAD, BPF_LINK_CREATE) and io_uring_setup/io_uring_enter on an orphaned ring; per kernel guidance io_uring and BPF are Local attack vectors with no remote packet path.\nAC:L - Exploitation is fully deterministic and attacker-controlled: create two DEFER_TASKRUN rings, link the same struct_ops map twice after dup2 repointing ring_fd, free the map/link, then io_uring_enter on the orphaned ring; no race or conditions outside attacker control are required.\nPR:L - The commit requires CAP_BPF and CAP_PERFMON, but bpf_token_capable() can delegate these into non-init user namespaces via BPF tokens in containerized deployments, and io_uring is commonly available to local users; under uncertainty this is scored Low rather than High.\nUI:N - No victim interaction is needed; once the attacker has BPF and io_uring access they can perform every setup, teardown, and triggering step themselves without any other user opening files or taking action.\nS:U - Impact is confined to kernel memory and execution within the same kernel security authority (standard local privilege-escalation/memory-corruption class), not a VM escape, IOMMU bypass, or other cross-scope boundary.\nC:H - Orphaned ctx->loop_step retains a pointer into a freed BPF struct_ops trampoline page; executing or dereferencing that UAF can expose reclaimed slab contents and supports building arbitrary read primitives, so confidentiality impact is High per UAF guidance.\nI:H - The dangling loop_step calls freed executable trampoline memory from io_run_loop(); with heap grooming an attacker can reclaim those pages with controlled contents, enabling control-flow hijack and arbitrary kernel write, so integrity impact is High.\nA:H - Invoking the dangling ctx->loop_step after trampoline teardown causes use-after-free of executable kernel memory during io_uring_enter, which can reliably trigger kernel oops, BUG, or panic and is repeatable on demand."}]}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["io_uring/bpf-ops.c"],"versions":[{"version":"98f37634b12b17ad5c56db8fb63cf9d7dc55d74c","lessThan":"0639ea767fe04c288a8d6cb826100fe3d95d4936","status":"affected","versionType":"git"},{"version":"98f37634b12b17ad5c56db8fb63cf9d7dc55d74c","lessThan":"3afc64c61ce906a04f073ca350b46de10e8302f9","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["io_uring/bpf-ops.c"],"versions":[{"version":"7.1","status":"affected"},{"version":"0","lessThan":"7.1","status":"unaffected","versionType":"semver"},{"version":"7.1.5","lessThanOrEqual":"7.1.*","status":"unaffected","versionType":"semver"},{"version":"7.2","lessThanOrEqual":"*","status":"unaffected","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"7.1","versionEndExcluding":"7.1.5"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"7.1","versionEndExcluding":"7.2"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/0639ea767fe04c288a8d6cb826100fe3d95d4936"},{"url":"https://git.kernel.org/stable/c/3afc64c61ce906a04f073ca350b46de10e8302f9"}],"title":"io_uring/bpf-ops: reject re-registration of an already-bound ops","x_generator":{"engine":"bippy-1.2.0"}}}}