microsoft / microsoft/ebpf-for-windows

ebpf_map_subscribe partial-failure rollback leaks per-CPU kernel mappings (cross-process blocked-map)

Open
#5,323 0 comments 0 reactions 1 assignee View on GitHub

@mikeagun is already working on this.

Since Jun 1, 2026.

bug P3 triaged
Dominant language
C
Stars
3.6k
Forks
311
Avg merge
6d 10h
Merged PRs (30d)
21

Description

ebpf_map_subscribe (libs/api/ebpf_api.cpp:5290-5346) iterates over cpu_ids[], mapping buffers and posting async IOCTLs for each CPU. If CPU k's MAP_QUERY_BUFFER or initialize_async_ioctl_operation fails (OOM, IO error), the function returns immediately at line 5302 or 5317 via EBPF_RETURN_RESULT(result) — bypassing the post-loop cleanup at lines 5343-5346 that calls ebpf_map_unsubscribe. The unique_ptr destructor for the subscription object only frees the raw allocation — it does NOT call the unsubscribe path.

CPUs 0..k-1 have ring buffers mapped in the kernel; their user_consumer_address fields remain set in the kernel ring descriptor. ebpf_free_ring_buffer_memory derefs user_process but does NOT clear user_consumer_address, so the stuck state survives the calling process's exit. Subsequent subscribe attempts to those CPU slots from any process are rejected by the kernel guard at libs/runtime/kernel/ebpf_platform_kernel.c:233-236 — the same cross-process kernel stuck-state mechanism that #5144 captured.

Additionally, in-flight async IOCTLs whose contexts are now orphaned can fire completion callbacks into freed user-mode state (process-local UAF).

The pattern survives code review because the post-loop cleanup looks comprehensive; the early returns are non-obvious exits from a long loop body. No existing test exercises a partial-failure mid-subscribe scenario.

Severity: high* — cross-process kernel blocked-map (same kernel-side mechanism as #5144), with * for the unusual partial-failure trigger (mid-subscribe OOM or IO error).

Discovered locally during code review of ebpf_api.cpp subscribe path. Fix in flight on fork branch mikeagun:fix/subscribe-robustness (commit e003dc142 adds proper subscribe/unsubscribe cleanup). Not yet opened as an upstream PR.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.