blob: 42d576ae6e6341d96a7654c195e719b6da875930 [file] [log] [blame]
{
"containers": {
"cna": {
"providerMetadata": {
"orgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038"
},
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nmm: zswap: properly synchronize freeing resources during CPU hotunplug\n\nIn zswap_compress() and zswap_decompress(), the per-CPU acomp_ctx of the\ncurrent CPU at the beginning of the operation is retrieved and used\nthroughout. However, since neither preemption nor migration are disabled,\nit is possible that the operation continues on a different CPU.\n\nIf the original CPU is hotunplugged while the acomp_ctx is still in use,\nwe run into a UAF bug as some of the resources attached to the acomp_ctx\nare freed during hotunplug in zswap_cpu_comp_dead() (i.e. \nacomp_ctx.buffer, acomp_ctx.req, or acomp_ctx.acomp).\n\nThe problem was introduced in commit 1ec3b5fe6eec (\"mm/zswap: move to use\ncrypto_acomp API for hardware acceleration\") when the switch to the\ncrypto_acomp API was made. Prior to that, the per-CPU crypto_comp was\nretrieved using get_cpu_ptr() which disables preemption and makes sure the\nCPU cannot go away from under us. Preemption cannot be disabled with the\ncrypto_acomp API as a sleepable context is needed.\n\nUse the acomp_ctx.mutex to synchronize CPU hotplug callbacks allocating\nand freeing resources with compression/decompression paths. Make sure\nthat acomp_ctx.req is NULL when the resources are freed. In the\ncompression/decompression paths, check if acomp_ctx.req is NULL after\nacquiring the mutex (meaning the CPU was offlined) and retry on the new\nCPU.\n\nThe initialization of acomp_ctx.mutex is moved from the CPU hotplug\ncallback to the pool initialization where it belongs (where the mutex is\nallocated). In addition to adding clarity, this makes sure that CPU\nhotplug cannot reinitialize a mutex that is already locked by\ncompression/decompression.\n\nPreviously a fix was attempted by holding cpus_read_lock() [1]. This\nwould have caused a potential deadlock as it is possible for code already\nholding the lock to fall into reclaim and enter zswap (causing a\ndeadlock). A fix was also attempted using SRCU for synchronization, but\nJohannes pointed out that synchronize_srcu() cannot be used in CPU hotplug\nnotifiers [2].\n\nAlternative fixes that were considered/attempted and could have worked:\n- Refcounting the per-CPU acomp_ctx. This involves complexity in\n handling the race between the refcount dropping to zero in\n zswap_[de]compress() and the refcount being re-initialized when the\n CPU is onlined.\n- Disabling migration before getting the per-CPU acomp_ctx [3], but\n that's discouraged and is a much bigger hammer than needed, and could\n result in subtle performance issues.\n\n[1]https://lkml.kernel.org/20241219212437.2714151-1-yosryahmed@google.com/\n[2]https://lkml.kernel.org/20250107074724.1756696-2-yosryahmed@google.com/\n[3]https://lkml.kernel.org/20250107222236.2715883-2-yosryahmed@google.com/\n\n[yosryahmed@google.com: remove comment]"
}
],
"affected": [
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "unaffected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"mm/zswap.c"
],
"versions": [
{
"version": "1ec3b5fe6eec782f4e5e0a80e4ce1909ffd5d161",
"lessThan": "8d29ff5d50304daa41dc3cfdda4a9d1e46cf5be1",
"status": "affected",
"versionType": "git"
},
{
"version": "1ec3b5fe6eec782f4e5e0a80e4ce1909ffd5d161",
"lessThan": "12dcb0ef540629a281533f9dedc1b6b8e14cfb65",
"status": "affected",
"versionType": "git"
}
]
},
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "affected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"mm/zswap.c"
],
"versions": [
{
"version": "5.11",
"status": "affected"
},
{
"version": "0",
"lessThan": "5.11",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.12.12",
"lessThanOrEqual": "6.12.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.13",
"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": "5.11",
"versionEndExcluding": "6.12.12"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "5.11",
"versionEndExcluding": "6.13"
}
]
}
]
}
],
"references": [
{
"url": "https://git.kernel.org/stable/c/8d29ff5d50304daa41dc3cfdda4a9d1e46cf5be1"
},
{
"url": "https://git.kernel.org/stable/c/12dcb0ef540629a281533f9dedc1b6b8e14cfb65"
}
],
"title": "mm: zswap: properly synchronize freeing resources during CPU hotunplug",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "f4215fc3-5b6b-47ff-a258-f7189bd81038",
"cveID": "CVE-2025-21693",
"requesterUserId": "gregkh@kernel.org",
"serial": "1",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.0"
}