{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2025-39941","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","state":"PUBLISHED","assignerShortName":"Linux","dateReserved":"2025-04-16T07:20:57.148Z","datePublished":"2025-10-04T07:31:04.080Z","dateUpdated":"2026-08-05T12:06:15.944Z"},"containers":{"cna":{"providerMetadata":{"orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux","dateUpdated":"2026-08-05T12:06:15.944Z"},"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nzram: fix slot write race condition\n\nParallel concurrent writes to the same zram index result in leaked\nzsmalloc handles.  Schematically we can have something like this:\n\nCPU0                              CPU1\nzram_slot_lock()\nzs_free(handle)\nzram_slot_lock()\n\t\t\t\tzram_slot_lock()\n\t\t\t\tzs_free(handle)\n\t\t\t\tzram_slot_lock()\n\ncompress\t\t\tcompress\nhandle = zs_malloc()\t\thandle = zs_malloc()\nzram_slot_lock\nzram_set_handle(handle)\nzram_slot_lock\n\t\t\t\tzram_slot_lock\n\t\t\t\tzram_set_handle(handle)\n\t\t\t\tzram_slot_lock\n\nEither CPU0 or CPU1 zsmalloc handle will leak because zs_free() is done\ntoo early.  In fact, we need to reset zram entry right before we set its\nnew handle, all under the same slot lock scope."}],"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 vulnerable code is the zram block-device write path (`zram_submit_bio` → `zram_write_page`), reached only through local block I/O — writes to /dev/zramN, a zram-backed filesystem, or zram swap. There is no network-facing consumer of this path.\nAC:L - The attacker controls both sides of the race: two threads issuing overlapping O_DIRECT or sub-page writes to the same 4 KiB index in a loop, with the window widened by the compress/zs_malloc stage and further by `zram_bvec_write_partial()`'s read-modify-write. The reporter reproduced it with an ordinary fio/blktests workload, and no attacker-uncontrollable condition is involved.\nPR:L - No capability check exists on the write path; the attacker only needs write access to a zram-backed device or filesystem, which unprivileged users routinely have on the dominant zram deployments (Android/ChromeOS swap, systemd zram-generator, embedded/automotive zram-backed /tmp, /var, or overlay upper dirs), or via membership in the `disk` group. Real root in the init namespace is not required.\nUI:N - The attacker's own two threads create and win the race entirely on their own. No victim action, mount, or file-open by another user is needed.\nS:U - The corruption is confined to the zram driver's slot table and zsmalloc pool within the kernel's own security authority. No VM, IOMMU, or sandbox boundary is crossed.\nC:H - The flag/handle desync yields two distinct kernel-memory disclosures into userspace-readable pages: a sticky ZRAM_SAME slot holding a real handle fills a whole 4 KiB page with a raw kernel heap pointer, and a sticky ZRAM_HUGE slot holding a small compressed object makes `read_incompressible_page()` `copy_page()` up to ~4 KiB of adjacent kernel memory past the end of the zspage.\nI:H - The race corrupts kernel slot metadata (handle, ZRAM_SAME/ZRAM_HUGE flags, obj_size) and the pool accounting counters, so stored page contents are silently replaced by kernel pointers or out-of-bounds heap data — corrupting file blocks or swapped-out anonymous pages belonging to other, potentially privileged, processes.\nA:H - `zs_obj_read_begin(pool, handle, NULL)` on a desynced ZRAM_HUGE slot whose object spans two zpdescs memcpys into a NULL `local_copy`, producing a kernel oops, alongside `WARN_ON` splats on decompression failure. Additionally, every won race permanently orphans a zsmalloc handle, an unbounded and repeatable leak that exhausts memory on the very device backing system swap."}]}],"affected":[{"product":"Linux","vendor":"Linux","defaultStatus":"unaffected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/zram/zram_drv.c"],"versions":[{"version":"71268035f5d734ad6373d953298bd5779985497a","lessThan":"ff750e9f2c4d63854c33967d1646b5e89a9a19a2","status":"affected","versionType":"git"},{"version":"71268035f5d734ad6373d953298bd5779985497a","lessThan":"ce4be9e4307c5a60701ff6e0cafa74caffdc54ce","status":"affected","versionType":"git"}]},{"product":"Linux","vendor":"Linux","defaultStatus":"affected","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/block/zram/zram_drv.c"],"versions":[{"version":"6.14","status":"affected"},{"version":"0","lessThan":"6.14","status":"unaffected","versionType":"semver"},{"version":"6.16.9","lessThanOrEqual":"6.16.*","status":"unaffected","versionType":"semver"},{"version":"6.17","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":"6.14","versionEndExcluding":"6.16.9"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.14","versionEndExcluding":"6.17"}]}]}],"references":[{"url":"https://git.kernel.org/stable/c/ff750e9f2c4d63854c33967d1646b5e89a9a19a2"},{"url":"https://git.kernel.org/stable/c/ce4be9e4307c5a60701ff6e0cafa74caffdc54ce"}],"title":"zram: fix slot write race condition","x_generator":{"engine":"bippy-1.2.0"}}}}