CVE-2025-39879
Full vulnerability record from the local CVENow database.
Description
In the Linux kernel, the following vulnerability has been resolved: ceph: always call ceph_shift_unused_folios_left() The function ceph_process_folio_batch() sets folio_batch entries to NULL, which is an illegal state. Before folio_batch_release() crashes due to this API violation, the function ceph_shift_unused_folios_left() is supposed to remove those NULLs from the array. However, since commit ce80b76dd327 ("ceph: introduce ceph_process_folio_batch() method"), this shifting doesn't happen anymore because the "for" loop got moved to ceph_process_folio_batch(), and now the `i` variable that remains in ceph_writepages_start() doesn't get incremented anymore, making the shifting effectively unreachable much of the time. Later, commit 1551ec61dc55 ("ceph: introduce ceph_submit_write() method") added more preconditions for doing the shift, replacing the `i` check (with something that is still just as broken): - if ceph_process_folio_batch() fails, shifting never happens - if ceph_move_dirty_page_in_page_array() was never called (because ceph_process_folio_batch() has returned early for some of various reasons), shifting never happens - if `processed_in_fbatch` is zero (because ceph_process_folio_batch() has returned early for some of the reasons mentioned above or because ceph_move_dirty_page_in_page_array() has failed), shifting never happens Since those two commits, any problem in ceph_process_folio_batch() could crash the kernel, e.g. this way: BUG: kernel NULL pointer dereference, address: 0000000000000034 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: Oops: 0002 [#1] SMP NOPTI CPU: 172 UID: 0 PID: 2342707 Comm: kworker/u778:8 Not tainted 6.15.10-cm4all1-es #714 NONE Hardware name: Dell Inc. PowerEdge R7615/0G9DHV, BIOS 1.6.10 12/08/2023 Workqueue: writeback wb_workfn (flush-ceph-1) RIP: 0010:folios_put_refs+0x85/0x140 Code: 83 c5 01 39 e8 7e 76 48 63 c5 49 8b 5c c4 08 b8 01 00 00 00 4d 85 ed 74 05 41 8b 44 ad 00 48 8b 15 b0 > RSP: 0018:ffffb880af8db778 EFLAGS: 00010207 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000003 RDX: ffffe377cc3b0000 RSI: 0000000000000000 RDI: ffffb880af8db8c0 RBP: 0000000000000000 R08: 000000000000007d R09: 000000000102b86f R10: 0000000000000001 R11: 00000000000000ac R12: ffffb880af8db8c0 R13: 0000000000000000 R14: 0000000000000000 R15: ffff9bd262c97000 FS: 0000000000000000(0000) GS:ffff9c8efc303000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000034 CR3: 0000000160958004 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> ceph_writepages_start+0xeb9/0x1410 The crash can be reproduced easily by changing the ceph_check_page_before_write() return value to `-E2BIG`. (Interestingly, the crash happens only if `huge_zero_folio` has already been allocated; without `huge_zero_folio`, is_huge_zero_folio(NULL) returns true and folios_put_refs() skips NULL entries instead of dereferencing them. That makes reproducing the bug somewhat unreliable. See https://lore.kernel.org/[email protected] for a discussion of this detail.) My suggestion is to move the ceph_shift_unused_folios_left() to right after ceph_process_folio_batch() to ensure it always gets called to fix up the illegal folio_batch state.
View original CVE JSON
{
"id": "CVE-2025-39879",
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"published": "2025-09-23T06:15:47.523",
"lastModified": "2026-10-21T13:18:16.270",
"vulnStatus": "Modified",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nceph: always call ceph_shift_unused_folios_left()\n\nThe function ceph_process_folio_batch() sets folio_batch entries to\nNULL, which is an illegal state. Before folio_batch_release() crashes\ndue to this API violation, the function ceph_shift_unused_folios_left()\nis supposed to remove those NULLs from the array.\n\nHowever, since commit ce80b76dd327 (\"ceph: introduce\nceph_process_folio_batch() method\"), this shifting doesn't happen\nanymore because the \"for\" loop got moved to ceph_process_folio_batch(),\nand now the `i` variable that remains in ceph_writepages_start()\ndoesn't get incremented anymore, making the shifting effectively\nunreachable much of the time.\n\nLater, commit 1551ec61dc55 (\"ceph: introduce ceph_submit_write()\nmethod\") added more preconditions for doing the shift, replacing the\n`i` check (with something that is still just as broken):\n\n- if ceph_process_folio_batch() fails, shifting never happens\n\n- if ceph_move_dirty_page_in_page_array() was never called (because\n ceph_process_folio_batch() has returned early for some of various\n reasons), shifting never happens\n\n- if `processed_in_fbatch` is zero (because ceph_process_folio_batch()\n has returned early for some of the reasons mentioned above or\n because ceph_move_dirty_page_in_page_array() has failed), shifting\n never happens\n\nSince those two commits, any problem in ceph_process_folio_batch()\ncould crash the kernel, e.g. this way:\n\n BUG: kernel NULL pointer dereference, address: 0000000000000034\n #PF: supervisor write access in kernel mode\n #PF: error_code(0x0002) - not-present page\n PGD 0 P4D 0\n Oops: Oops: 0002 [#1] SMP NOPTI\n CPU: 172 UID: 0 PID: 2342707 Comm: kworker/u778:8 Not tainted 6.15.10-cm4all1-es #714 NONE\n Hardware name: Dell Inc. PowerEdge R7615/0G9DHV, BIOS 1.6.10 12/08/2023\n Workqueue: writeback wb_workfn (flush-ceph-1)\n RIP: 0010:folios_put_refs+0x85/0x140\n Code: 83 c5 01 39 e8 7e 76 48 63 c5 49 8b 5c c4 08 b8 01 00 00 00 4d 85 ed 74 05 41 8b 44 ad 00 48 8b 15 b0 >\n RSP: 0018:ffffb880af8db778 EFLAGS: 00010207\n RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000003\n RDX: ffffe377cc3b0000 RSI: 0000000000000000 RDI: ffffb880af8db8c0\n RBP: 0000000000000000 R08: 000000000000007d R09: 000000000102b86f\n R10: 0000000000000001 R11: 00000000000000ac R12: ffffb880af8db8c0\n R13: 0000000000000000 R14: 0000000000000000 R15: ffff9bd262c97000\n FS: 0000000000000000(0000) GS:ffff9c8efc303000(0000) knlGS:0000000000000000\n CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n CR2: 0000000000000034 CR3: 0000000160958004 CR4: 0000000000770ef0\n PKRU: 55555554\n Call Trace:\n <TASK>\n ceph_writepages_start+0xeb9/0x1410\n\nThe crash can be reproduced easily by changing the\nceph_check_page_before_write() return value to `-E2BIG`.\n\n(Interestingly, the crash happens only if `huge_zero_folio` has\nalready been allocated; without `huge_zero_folio`,\nis_huge_zero_folio(NULL) returns true and folios_put_refs() skips NULL\nentries instead of dereferencing them. That makes reproducing the bug\nsomewhat unreliable. See\nhttps://lore.kernel.org/[email protected]\nfor a discussion of this detail.)\n\nMy suggestion is to move the ceph_shift_unused_folios_left() to right\nafter ceph_process_folio_batch() to ensure it always gets called to\nfix up the illegal folio_batch state."
},
{
"lang": "es",
"value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\nceph: llamar siempre a ceph_shift_unused_folios_left()\n\nLa función ceph_process_folio_batch() establece las entradas de folio_batch a NULL, lo cual es un estado ilegal. Antes de que folio_batch_release() falle debido a esta violación de la API, se supone que la función ceph_shift_unused_folios_left() debe eliminar esos NULLs del array.\n\nSin embargo, desde el commit ce80b76dd327 ('ceph: introduce el método ceph_process_folio_batch()'), este desplazamiento ya no ocurre porque el bucle 'for' se movió a ceph_process_folio_batch(), y ahora la variable 'i' que permanece en ceph_writepages_start() ya no se incrementa, haciendo que el desplazamiento sea efectivamente inalcanzable la mayor parte del tiempo.\n\nMás tarde, el commit 1551ec61dc55 ('ceph: introduce el método ceph_submit_write()') añadió más precondiciones para realizar el desplazamiento, reemplazando la comprobación de 'i' (con algo que sigue estando igual de roto):\n\n- si ceph_process_folio_batch() falla, el desplazamiento nunca ocurre\n\n- si ceph_move_dirty_page_in_page_array() nunca fue llamada (porque ceph_process_folio_batch() ha retornado anticipadamente por alguna de varias razones), el desplazamiento nunca ocurre\n\n- si 'processed_in_fbatch' es cero (porque ceph_process_folio_batch() ha retornado anticipadamente por alguna de las razones mencionadas anteriormente o porque ceph_move_dirty_page_in_page_array() ha fallado), el desplazamiento nunca ocurre\n\nDesde esos dos commits, cualquier problema en ceph_process_folio_batch() podría bloquear el kernel, por ejemplo, de esta manera:\n\n BUG: desreferencia de puntero NULL del kernel, dirección: 0000000000000034\n #PF: acceso de escritura de supervisor en modo kernel\n #PF: error_code(0x0002) - página no presente\n PGD 0 P4D 0\n Oops: Oops: 0002 [#1] SMP NOPTI\n CPU: 172 UID: 0 PID: 2342707 Comm: kworker/u778:8 Not tainted 6.15.10-cm4all1-es #714 NONE\n Hardware name: Dell Inc. PowerEdge R7615/0G9DHV, BIOS 1.6.10 12/08/2023\n Workqueue: writeback wb_workfn (flush-ceph-1)\n RIP: 0010:folios_put_refs+0x85/0x140\n Code: 83 c5 01 39 e8 7e 76 48 63 c5 49 8b 5c c4 08 b8 01 00 00 00 4d 85 ed 74 05 41 8b 44 ad 00 48 8b 15 b0 >\n RSP: 0018:ffffb880af8db778 EFLAGS: 00010207\n RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000003\n RDX: ffffe377cc3b0000 RSI: 0000000000000000 RDI: ffffb880af8db8c0\n RBP: 0000000000000000 R08: 000000000000007d R09: 000000000102b86f\n R10: 0000000000000001 R11: 00000000000000ac R12: ffffb880af8db8c0\n R13: 0000000000000000 R14: 0000000000000000 R15: ffff9bd262c97000\n FS: 0000000000000000(0000) GS:ffff9c8efc303000(0000) knlGS:0000000000000000\n CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n CR2: 0000000000000034 CR3: 0000000160958004 CR4: 0000000000770ef0\n PKRU: 55555554\n Traza de Llamadas:\n <TASK>\n ceph_writepages_start+0xeb9/0x1410\n\nEl fallo se puede reproducir fácilmente cambiando el valor de retorno de ceph_check_page_before_write() a '-E2BIG'.\n\n(Curiosamente, el fallo ocurre solo si 'huge_zero_folio' ya ha sido asignado; sin 'huge_zero_folio', is_huge_zero_folio(NULL) retorna verdadero y folios_put_refs() omite las entradas NULL en lugar de desreferenciarlas. Eso hace que la reproducción del error sea algo poco fiable. Ver https://lore.kernel.org/[email protected] para una discusión de este detalle.)\n\nMi sugerencia es mover ceph_shift_unused_folios_left() justo después de ceph_process_folio_batch() para asegurar que siempre sea llamada para corregir el estado ilegal de folio_batch."
}
],
"affected": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"affectedData": [
{
"vendor": "Linux",
"product": "Linux",
"defaultStatus": "unaffected",
"programFiles": [
"fs/ceph/addr.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"versions": [
{
"version": "0f2b2b7cacf888229cec19126e6791b11fb35f32",
"lessThan": "523214f0afa1b3d0e696917bc5a4d0737718e3d7",
"versionType": "git",
"status": "affected"
},
{
"version": "ce80b76dd32764cc914975777e058d4fae4f0ea0",
"lessThan": "289b6615cf553d98509a9b273195d9936da1cfb2",
"versionType": "git",
"status": "affected"
},
{
"version": "ce80b76dd32764cc914975777e058d4fae4f0ea0",
"lessThan": "cce7c15faaac79b532a07ed6ab8332280ad83762",
"versionType": "git",
"status": "affected"
}
]
},
{
"vendor": "Linux",
"product": "Linux",
"defaultStatus": "affected",
"programFiles": [
"fs/ceph/addr.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"versions": [
{
"version": "6.15",
"status": "affected"
},
{
"version": "0",
"lessThan": "6.15",
"versionType": "semver",
"status": "unaffected"
},
{
"version": "6.16.8",
"lessThanOrEqual": "6.16.*",
"versionType": "semver",
"status": "unaffected"
},
{
"version": "6.17",
"lessThanOrEqual": "*",
"versionType": "original_commit_for_fix",
"status": "unaffected"
}
]
}
]
}
],
"metrics": {
"cvssMetricV31": [
{
"source": "[email protected]",
"type": "Primary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"baseScore": 5.5,
"baseSeverity": "MEDIUM",
"attackVector": "LOCAL",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 1.8,
"impactScore": 3.6
},
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"type": "Secondary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
"baseScore": 5.5,
"baseSeverity": "MEDIUM",
"attackVector": "LOCAL",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 1.8,
"impactScore": 3.6
}
],
"ssvcV203": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"ssvcData": {
"timestamp": "2026-01-14T19:25:25.258616Z",
"id": "CVE-2025-39879",
"options": [
{
"exploitation": "none"
},
{
"automatable": "no"
},
{
"technicalImpact": "partial"
}
],
"role": "CISA Coordinator",
"version": "2.0.3"
}
}
]
},
"weaknesses": [
{
"source": "[email protected]",
"type": "Primary",
"description": [
{
"lang": "en",
"value": "CWE-476"
}
]
},
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-476"
}
]
}
],
"configurations": [
{
"nodes": [
{
"operator": "OR",
"negate": false,
"cpeMatch": [
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "6.15",
"versionEndExcluding": "6.16.8",
"matchCriteriaId": "4CDBA6F5-ADD5-4E49-89EE-9FA2364F2685"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:6.17:rc1:*:*:*:*:*:*",
"matchCriteriaId": "327D22EF-390B-454C-BD31-2ED23C998A1C"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:6.17:rc2:*:*:*:*:*:*",
"matchCriteriaId": "C730CD9A-D969-4A8E-9522-162AAF7C0EE9"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:6.17:rc3:*:*:*:*:*:*",
"matchCriteriaId": "39982C4B-716E-4B2F-8196-FA301F47807D"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:6.17:rc4:*:*:*:*:*:*",
"matchCriteriaId": "340BEEA9-D70D-4290-B502-FBB1032353B1"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:6.17:rc5:*:*:*:*:*:*",
"matchCriteriaId": "47E4C5C0-079F-4838-971B-8C503D48FCC2"
}
]
}
]
}
],
"references": [
{
"url": "https://git.kernel.org/stable/c/289b6615cf553d98509a9b273195d9936da1cfb2",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"tags": [
"Patch"
]
},
{
"url": "https://git.kernel.org/stable/c/523214f0afa1b3d0e696917bc5a4d0737718e3d7",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/cce7c15faaac79b532a07ed6ab8332280ad83762",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"tags": [
"Patch"
]
}
]
}