Skip to content

Commit

Permalink
cpufreq: stats: Fix buffer overflow detection in trans_stats()
Browse files Browse the repository at this point in the history
[ Upstream commit ea167a7 ]

Commit 3c0897c ("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: 3c0897c ("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>
  • Loading branch information
Ansuel authored and gregkh committed Nov 28, 2023
1 parent c2d1468 commit e785584
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions drivers/cpufreq/cpufreq_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down

0 comments on commit e785584

Please sign in to comment.