CVE-2026-46253
Description
Linux kernel pstore/ram component has a heap buffer overflow in persistent_ram_save_old() due to incorrect size handling.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Linux kernel pstore/ram component has a heap buffer overflow in persistent_ram_save_old() due to incorrect size handling.
Vulnerability
The Linux kernel's pstore/ram component contains a heap buffer overflow vulnerability in the persistent_ram_save_old() function. This function can be called multiple times for the same persistent ram zone. While it only allocates prz->old_log when it's NULL, it unconditionally updates prz->old_log_size to the current buffer size and then performs memcpy_fromio() using this new size. If the buffer size has increased since the initial allocation across different kernel boot cycles, this leads to an out-of-bounds write during memcpy_fromio() and a subsequent out-of-bounds read when ramoops_pstore_read() accesses the buffer with the incorrect, larger old_log_size. This affects versions prior to the fix in the pstore/ram module [1].
Exploitation
Exploiting this vulnerability is considered extremely difficult and requires a specific sequence of events. An attacker would need a prior crash record that did not fill the record size, followed by a reboot. During the subsequent boot, pstore_get_records(0) reads the old crash data, allocating old_log with size X. If a non-fatal oops occurs, pstore_dump() writes the oops via ramops_pstore_write() with a new size Y, where Y > X. After a delay, pstore_timefunc() triggers pstore_get_records(1), which calls persistent_ram_save_old(). At this point, buffer_size() returns Y, but old_log is only X bytes, leading to the heap overflow during memcpy_fromio() [1].
Impact
Successful exploitation of this vulnerability results in a heap buffer overflow (out-of-bounds write) during memcpy_fromio() and a subsequent out-of-bounds read when accessing the corrupted buffer. This can lead to arbitrary code execution within the kernel, potentially allowing an attacker to gain complete control over the affected system. The KASAN splat indicates a slab-out-of-bounds read in ramops_pstore_read [1].
Mitigation
The vulnerability has been resolved in the Linux kernel with a fix committed to the pstore/ram module. The specific fixed version is not detailed in the provided references, but the commit hash is 7cfe964e61c0ab667abd5f5b68e0acbf783efa4f [1]. No workarounds are described, and it is not indicated if the affected component is end-of-life or listed on the KEV. Users are advised to update to a patched version of the Linux kernel as soon as it becomes available.
AI Insight generated on Jun 3, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
1658bda5a1d1eepstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 5ac9b1f155a81..97ec9041b9b98 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
06d2c8bd108cpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index ec321722384dc..8eb4bea7295b4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
2fa9a047c6a5pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f479e0755a247..03d586f1ebc8c 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
cff0ef043e16pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
9a6fc69a570cpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
4f73486ca822pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
7cfe964e61c0pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
5669645c052fpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f8b9b47e8b244..7b6d6378a3b87 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
9a6fc69a570cpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
4f73486ca822pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
2fa9a047c6a5pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f479e0755a247..03d586f1ebc8c 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
06d2c8bd108cpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index ec321722384dc..8eb4bea7295b4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
5669645c052fpstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f8b9b47e8b244..7b6d6378a3b87 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
58bda5a1d1eepstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 5ac9b1f155a81..97ec9041b9b98 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kmalloc(size, GFP_KERNEL); -- cgit 1.3-korg
7cfe964e61c0pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
cff0ef043e16pstore/ram: fix buffer overflow in persistent_ram_save_old()
1 file changed · +11 −1
fs/pstore/ram_core.c+11 −1 modifieddiff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index f1848cdd6d348..c9eaacdec37e4 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,6 +298,17 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz) if (!size) return; + /* + * If the existing buffer is differently sized, free it so a new + * one is allocated. This can happen when persistent_ram_save_old() + * is called early in boot and later for a timer-triggered + * survivable crash when the crash dumps don't match in size + * (which would be extremely unlikely given kmsg buffers usually + * exceed prz buffer sizes). + */ + if (prz->old_log && prz->old_log_size != size) + persistent_ram_free_old(prz); + if (!prz->old_log) { persistent_ram_ecc_old(prz); prz->old_log = kvzalloc(size, GFP_KERNEL); -- cgit 1.3-korg
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
8- git.kernel.org/stable/c/06d2c8bd108cea503f6f6e13e47495ed1085275fnvd
- git.kernel.org/stable/c/2fa9a047c6a50ec80c3890dd623b85e237f0d1fdnvd
- git.kernel.org/stable/c/4f73486ca822305c1cf5b8ebc0b53a6ab3801a81nvd
- git.kernel.org/stable/c/5669645c052f235726a85f443769b6fc02f66762nvd
- git.kernel.org/stable/c/58bda5a1d1ee98254383ef34f76b2c35140513eanvd
- git.kernel.org/stable/c/7cfe964e61c0ab667abd5f5b68e0acbf783efa4fnvd
- git.kernel.org/stable/c/9a6fc69a570c0780834246d52c856cc3dbc2605fnvd
- git.kernel.org/stable/c/cff0ef043e16feb5a02307c8f9d0117a96c5587cnvd
News mentions
1- Linux Kernel: 25 Vulnerabilities Disclosed in Single Batch on June 3, 2026Vypr Intelligence · Jun 3, 2026