Skip to content

Commit ea167a7

Browse files
Ansuelrafaeljw
authored andcommitted
cpufreq: stats: Fix buffer overflow detection in trans_stats()
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+ <[email protected]> # 5.10+ Fixes: 3c0897c ("cpufreq: Use scnprintf() for avoiding potential buffer overflow") Signed-off-by: Christian Marangi <[email protected]> [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent e7a1b32 commit ea167a7

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

drivers/cpufreq/cpufreq_stats.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,23 +131,23 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
131131
len += sysfs_emit_at(buf, len, " From : To\n");
132132
len += sysfs_emit_at(buf, len, " : ");
133133
for (i = 0; i < stats->state_num; i++) {
134-
if (len >= PAGE_SIZE)
134+
if (len >= PAGE_SIZE - 1)
135135
break;
136136
len += sysfs_emit_at(buf, len, "%9u ", stats->freq_table[i]);
137137
}
138-
if (len >= PAGE_SIZE)
139-
return PAGE_SIZE;
138+
if (len >= PAGE_SIZE - 1)
139+
return PAGE_SIZE - 1;
140140

141141
len += sysfs_emit_at(buf, len, "\n");
142142

143143
for (i = 0; i < stats->state_num; i++) {
144-
if (len >= PAGE_SIZE)
144+
if (len >= PAGE_SIZE - 1)
145145
break;
146146

147147
len += sysfs_emit_at(buf, len, "%9u: ", stats->freq_table[i]);
148148

149149
for (j = 0; j < stats->state_num; j++) {
150-
if (len >= PAGE_SIZE)
150+
if (len >= PAGE_SIZE - 1)
151151
break;
152152

153153
if (pending)
@@ -157,12 +157,12 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
157157

158158
len += sysfs_emit_at(buf, len, "%9u ", count);
159159
}
160-
if (len >= PAGE_SIZE)
160+
if (len >= PAGE_SIZE - 1)
161161
break;
162162
len += sysfs_emit_at(buf, len, "\n");
163163
}
164164

165-
if (len >= PAGE_SIZE) {
165+
if (len >= PAGE_SIZE - 1) {
166166
pr_warn_once("cpufreq transition table exceeds PAGE_SIZE. Disabling\n");
167167
return -EFBIG;
168168
}

0 commit comments

Comments
 (0)