From: Greg Kroah-Hartman Date: Mon, 29 Apr 2024 11:15:14 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.19.313~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2ec1c8e30df46ee8d50d10780fee932c8eb3b383;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch --- diff --git a/queue-5.10/pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch b/queue-5.10/pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch new file mode 100644 index 00000000000..fc95ba4344d --- /dev/null +++ b/queue-5.10/pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch @@ -0,0 +1,141 @@ +From 08e23d05fa6dc4fc13da0ccf09defdd4bbc92ff4 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 24 Oct 2023 20:30:15 +0200 +Subject: PM / devfreq: Fix buffer overflow in trans_stat_show + +From: Christian Marangi + +commit 08e23d05fa6dc4fc13da0ccf09defdd4bbc92ff4 upstream. + +Fix buffer overflow in trans_stat_show(). + +Convert simple snprintf to the more secure scnprintf with size of +PAGE_SIZE. + +Add condition checking if we are exceeding PAGE_SIZE and exit early from +loop. Also add at the end a warning that we exceeded PAGE_SIZE and that +stats is disabled. + +Return -EFBIG in the case where we don't have enough space to write the +full transition table. + +Also document in the ABI that this function can return -EFBIG error. + +Link: https://lore.kernel.org/all/20231024183016.14648-2-ansuelsmth@gmail.com/ +Cc: stable@vger.kernel.org +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218041 +Fixes: e552bbaf5b98 ("PM / devfreq: Add sysfs node for representing frequency transition information.") +Signed-off-by: Christian Marangi +Signed-off-by: Chanwoo Choi +Signed-off-by: Sasha Levin +Signed-off-by: Jan Kiszka +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-class-devfreq | 3 + + drivers/devfreq/devfreq.c | 59 +++++++++++++++++--------- + 2 files changed, 43 insertions(+), 19 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-class-devfreq ++++ b/Documentation/ABI/testing/sysfs-class-devfreq +@@ -66,6 +66,9 @@ Description: + + echo 0 > /sys/class/devfreq/.../trans_stat + ++ If the transition table is bigger than PAGE_SIZE, reading ++ this will return an -EFBIG error. ++ + What: /sys/class/devfreq/.../userspace/set_freq + Date: September 2011 + Contact: MyungJoo Ham +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -1639,7 +1639,7 @@ static ssize_t trans_stat_show(struct de + struct device_attribute *attr, char *buf) + { + struct devfreq *df = to_devfreq(dev); +- ssize_t len; ++ ssize_t len = 0; + int i, j; + unsigned int max_state; + +@@ -1648,7 +1648,7 @@ static ssize_t trans_stat_show(struct de + max_state = df->profile->max_state; + + if (max_state == 0) +- return sprintf(buf, "Not Supported.\n"); ++ return scnprintf(buf, PAGE_SIZE, "Not Supported.\n"); + + mutex_lock(&df->lock); + if (!df->stop_polling && +@@ -1658,33 +1658,54 @@ static ssize_t trans_stat_show(struct de + } + mutex_unlock(&df->lock); + +- len = sprintf(buf, " From : To\n"); +- len += sprintf(buf + len, " :"); +- for (i = 0; i < max_state; i++) +- len += sprintf(buf + len, "%10lu", +- df->profile->freq_table[i]); ++ len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n"); ++ len += scnprintf(buf + len, PAGE_SIZE - len, " :"); ++ for (i = 0; i < max_state; i++) { ++ if (len >= PAGE_SIZE - 1) ++ break; ++ len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu", ++ df->profile->freq_table[i]); ++ } ++ if (len >= PAGE_SIZE - 1) ++ return PAGE_SIZE - 1; + +- len += sprintf(buf + len, " time(ms)\n"); ++ len += scnprintf(buf + len, PAGE_SIZE - len, " time(ms)\n"); + + for (i = 0; i < max_state; i++) { ++ if (len >= PAGE_SIZE - 1) ++ break; + if (df->profile->freq_table[i] + == df->previous_freq) { +- len += sprintf(buf + len, "*"); ++ len += scnprintf(buf + len, PAGE_SIZE - len, "*"); + } else { +- len += sprintf(buf + len, " "); ++ len += scnprintf(buf + len, PAGE_SIZE - len, " "); + } +- len += sprintf(buf + len, "%10lu:", +- df->profile->freq_table[i]); +- for (j = 0; j < max_state; j++) +- len += sprintf(buf + len, "%10u", +- df->stats.trans_table[(i * max_state) + j]); ++ if (len >= PAGE_SIZE - 1) ++ break; ++ ++ len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu:", ++ df->profile->freq_table[i]); ++ for (j = 0; j < max_state; j++) { ++ if (len >= PAGE_SIZE - 1) ++ break; ++ len += scnprintf(buf + len, PAGE_SIZE - len, "%10u", ++ df->stats.trans_table[(i * max_state) + j]); ++ } ++ if (len >= PAGE_SIZE - 1) ++ break; ++ len += scnprintf(buf + len, PAGE_SIZE - len, "%10llu\n", (u64) ++ jiffies64_to_msecs(df->stats.time_in_state[i])); ++ } + +- len += sprintf(buf + len, "%10llu\n", (u64) +- jiffies64_to_msecs(df->stats.time_in_state[i])); ++ if (len < PAGE_SIZE - 1) ++ len += scnprintf(buf + len, PAGE_SIZE - len, "Total transition : %u\n", ++ df->stats.total_trans); ++ ++ if (len >= PAGE_SIZE - 1) { ++ pr_warn_once("devfreq transition table exceeds PAGE_SIZE. Disabling\n"); ++ return -EFBIG; + } + +- len += sprintf(buf + len, "Total transition : %u\n", +- df->stats.total_trans); + return len; + } + diff --git a/queue-5.10/series b/queue-5.10/series index 8cdd2fcab2a..38a8ac5e7ca 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -110,3 +110,4 @@ revert-crypto-api-disallow-identical-driver-names.patch net-mlx5e-fix-a-race-in-command-alloc-flow.patch tracing-show-size-of-requested-perf-buffer.patch tracing-increase-perf_max_trace_size-to-handle-sentinel1-and-docker-together.patch +pm-devfreq-fix-buffer-overflow-in-trans_stat_show.patch