CVE-2026-45881
Description
In the Linux kernel, the following vulnerability has been resolved:
soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
In svs_enable_debug_write(), the buf allocated by memdup_user_nul() is leaked if kstrtoint() fails.
Fix this by using __free(kfree) to automatically free buf, eliminating the need for explicit kfree() calls and preventing leaks.
[Angelo: Added missing cleanup.h inclusion]
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A memory leak in the Mediatek SVS driver's svs_enable_debug_write() function is fixed by using automatic cleanup to free a buffer on error.
Vulnerability
In the Linux kernel, the Mediatek System Voltage Scaling (SVS) driver contains a memory leak in the svs_enable_debug_write() function. The function allocates a kernel buffer via memdup_user_nul() to copy user-provided data, but if the subsequent kstrtoint() call fails, the buffer is not freed, leading to a memory leak. This affects the svs_enable_debug_write() function in the drivers/soc/mediatek/mtk-svs.c file. The fix was applied to the stable kernel tree; the affected versions are those prior to the inclusion of commit a58c97828911 [1].
Exploitation
An attacker with the ability to write to the SVS debug interface (typically requiring root or privileged access to the /sys/kernel/debug/ filesystem) can trigger the leak by providing input that causes kstrtoint() to fail. No special race window or user interaction beyond writing a malformed string to the debug file is needed. The failure path in svs_enable_debug_write() is reachable when the user-supplied string cannot be converted to an integer.
Impact
Successful exploitation results in a kernel memory leak, which can gradually deplete system memory. While this is not an immediate compromise of confidentiality, integrity, or availability, repeated exploitation could lead to a denial-of-service condition due to memory exhaustion. The leak is local and requires debug interface access, so the overall impact is limited.
Mitigation
The fix is contained in Linux kernel commit a58c97828911c0b6e25d6b556789da974003efda, which replaces explicit kfree() calls with the __free(kfree) automatic cleanup mechanism and adds the necessary #include <linux/cleanup.h>. Users should update to a kernel version that includes this commit. No workarounds are mentioned in the available references. The vulnerability is not known to be listed on CISA's KEV.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
126259094ee806soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
47a3e372f7d6soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 1ec6e631a77960..9897905a65baf4 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -7,6 +7,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -709,7 +710,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_platform *svsp = dev_get_drvdata(svsb->dev); unsigned long flags; int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -735,8 +736,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svs_adjust_pm_opp_volts(svsb); } - kfree(buf); - return count; } -- cgit 1.3-korg
06195456c4e4soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 3a2f97cd527200..37d21e3de69423 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -7,6 +7,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -717,7 +718,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -735,8 +736,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
6bb10466e088soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
a58c97828911soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 4cb8169aec6b55..07ab261e1269d0 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
0f6498077faasoc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
0f6498077faasoc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
06195456c4e4soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 3a2f97cd527200..37d21e3de69423 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -7,6 +7,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -717,7 +718,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -735,8 +736,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
6bb10466e088soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
a58c97828911soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 4cb8169aec6b55..07ab261e1269d0 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
6259094ee806soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index f45537546553ec..99edecb204f254 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -9,6 +9,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -789,7 +790,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_bank *svsb = file_inode(filp)->i_private; struct svs_platform *svsp = dev_get_drvdata(svsb->dev); int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -807,8 +808,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svsb->mode_support = SVSB_MODE_ALL_DISABLE; } - kfree(buf); - return count; } -- cgit 1.3-korg
47a3e372f7d6soc: mediatek: svs: Fix memory leak in svs_enable_debug_write()
1 file changed · +2 −4
drivers/soc/mediatek/mtk-svs.c+2 −4 modifieddiff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index 1ec6e631a77960..9897905a65baf4 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -7,6 +7,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cleanup.h> #include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> @@ -709,7 +710,7 @@ static ssize_t svs_enable_debug_write(struct file *filp, struct svs_platform *svsp = dev_get_drvdata(svsb->dev); unsigned long flags; int enabled, ret; - char *buf = NULL; + char *buf __free(kfree) = NULL; if (count >= PAGE_SIZE) return -EINVAL; @@ -735,8 +736,6 @@ static ssize_t svs_enable_debug_write(struct file *filp, svs_adjust_pm_opp_volts(svsb); } - kfree(buf); - return count; } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing deallocation of heap-allocated buffer when kstrtoint() fails in svs_enable_debug_write()."
Attack vector
An attacker with access to the Mediatek SVS debugfs interface writes a value to the "enable" debugfs file. The kernel copies the user-supplied string into a heap buffer via memdup_user_nul() and then calls kstrtoint() to parse it. If kstrtoint() fails (e.g. because the string is not a valid integer), the function returns an error code without freeing the buffer, causing a memory leak. Repeated exploitation can exhaust kernel memory.
Affected code
The vulnerable function is `svs_enable_debug_write()` in `drivers/soc/mediatek/mtk-svs.c`. The function allocates a buffer via `memdup_user_nul()` and parses it with `kstrtoint()`, but if parsing fails the buffer is not freed before returning.
What the fix does
The patch replaces the raw `char *buf` declaration with `char *buf __free(kfree)`, which uses the kernel's automatic cleanup attribute to call kfree() when `buf` goes out of scope. This ensures the buffer is freed on every code path, including the error return from kstrtoint(). The explicit `kfree(buf)` at the end of the function is removed as it is now handled automatically. The patch also adds `#include <linux/cleanup.h>` which provides the `__free()` macro.
Preconditions
- authThe attacker must have access to the Mediatek SVS debugfs interface (typically requires root or debugfs mount access).
- inputThe attacker must be able to write to the 'enable' debugfs file for an SVS bank.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- git.kernel.org/stable/c/06195456c4e4de3826c4ca60eca941c472f991d0nvd
- git.kernel.org/stable/c/0f6498077faa9cd89bb787bcc57063494a6f0601nvd
- git.kernel.org/stable/c/47a3e372f7d68776adb749a27c0ec9058ff1b4fdnvd
- git.kernel.org/stable/c/6259094ee806fb813ca95894c65fb80e2ec98bf1nvd
- git.kernel.org/stable/c/6bb10466e0884b4a68d4a1f3f4bb87eeb471c18anvd
- git.kernel.org/stable/c/a58c97828911c0b6e25d6b556789da974003efdanvd
News mentions
0No linked articles in our index yet.