summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Marangi <ansuelsmth@gmail.com>2023-10-24 20:30:14 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-28 16:54:59 +0000
commit8617305611c16e124d1b8f2ce73c008bc9119f93 (patch)
tree126baff02692a78b3657dc58fe47a3596e40893d
parent2ed25af15b32a49f387984fb9d5be6d1086a885a (diff)
downloadlinux-8617305611c16e124d1b8f2ce73c008bc9119f93.tar.gz
linux-8617305611c16e124d1b8f2ce73c008bc9119f93.tar.bz2
linux-8617305611c16e124d1b8f2ce73c008bc9119f93.zip
cpufreq: stats: Fix buffer overflow detection in trans_stats()
[ Upstream commit ea167a7fc2426f7685c3735e104921c1a20a6d3f ] Commit 3c0897c180c6 ("cpufreq: Use scnprintf() for avoiding potential buffer overflow") switched from snprintf to the more secure scnprintf but never updated the exit condition for PAGE_SIZE. As the commit say and as scnprintf document, what scnprintf returns what is actually written not counting the '\0' end char. This results in the case of len exceeding the size, len set to PAGE_SIZE - 1, as it can be written at max PAGE_SIZE - 1 (as '\0' is not counted) Because of len is never set to PAGE_SIZE, the function never break early, never prints the warning and never return -EFBIG. Fix this by changing the condition to PAGE_SIZE - 1 to correctly trigger the error. Cc: 5.10+ <stable@vger.kernel.org> # 5.10+ Fixes: 3c0897c180c6 ("cpufreq: Use scnprintf() for avoiding potential buffer overflow") Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/cpufreq/cpufreq_stats.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 6cd5c8ab5d49..ab856dd2d5fc 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -131,25 +131,25 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n");
len += scnprintf(buf + len, PAGE_SIZE - len, " : ");
for (i = 0; i < stats->state_num; i++) {
- if (len >= PAGE_SIZE)
+ if (len >= PAGE_SIZE - 1)
break;
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
stats->freq_table[i]);
}
- if (len >= PAGE_SIZE)
- return PAGE_SIZE;
+ if (len >= PAGE_SIZE - 1)
+ return PAGE_SIZE - 1;
len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
for (i = 0; i < stats->state_num; i++) {
- if (len >= PAGE_SIZE)
+ if (len >= PAGE_SIZE - 1)
break;
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u: ",
stats->freq_table[i]);
for (j = 0; j < stats->state_num; j++) {
- if (len >= PAGE_SIZE)
+ if (len >= PAGE_SIZE - 1)
break;
if (pending)
@@ -159,12 +159,12 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", count);
}
- if (len >= PAGE_SIZE)
+ if (len >= PAGE_SIZE - 1)
break;
len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
}
- if (len >= PAGE_SIZE) {
+ if (len >= PAGE_SIZE - 1) {
pr_warn_once("cpufreq transition table exceeds PAGE_SIZE. Disabling\n");
return -EFBIG;
}