+++ /dev/null
-From 6e0198428dac397668410194d2f454750ee7f1d4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 29 Oct 2020 15:11:03 +0000
-Subject: sched/debug: Fix memory corruption caused by multiple small reads of
- flags
-
-From: Colin Ian King <colin.king@canonical.com>
-
-[ Upstream commit 8d4d9c7b4333abccb3bf310d76ef7ea2edb9828f ]
-
-Reading /proc/sys/kernel/sched_domain/cpu*/domain0/flags mutliple times
-with small reads causes oopses with slub corruption issues because the kfree is
-free'ing an offset from a previous allocation. Fix this by adding in a new
-pointer 'buf' for the allocation and kfree and use the temporary pointer tmp
-to handle memory copies of the buf offsets.
-
-Fixes: 5b9f8ff7b320 ("sched/debug: Output SD flag names rather than their values")
-Reported-by: Jeff Bastian <jbastian@redhat.com>
-Signed-off-by: Colin Ian King <colin.king@canonical.com>
-Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
-Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
-Link: https://lkml.kernel.org/r/20201029151103.373410-1-colin.king@canonical.com
-Stable-dep-of: c2e406596571 ("sched/debug: fix dentry leak in update_sched_domain_debugfs")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/sched/debug.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
-index df646776b7f0..5cb097382c47 100644
---- a/kernel/sched/debug.c
-+++ b/kernel/sched/debug.c
-@@ -249,7 +249,7 @@ static int sd_ctl_doflags(struct ctl_table *table, int write,
- unsigned long flags = *(unsigned long *)table->data;
- size_t data_size = 0;
- size_t len = 0;
-- char *tmp;
-+ char *tmp, *buf;
- int idx;
-
- if (write)
-@@ -267,17 +267,17 @@ static int sd_ctl_doflags(struct ctl_table *table, int write,
- return 0;
- }
-
-- tmp = kcalloc(data_size + 1, sizeof(*tmp), GFP_KERNEL);
-- if (!tmp)
-+ buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL);
-+ if (!buf)
- return -ENOMEM;
-
- for_each_set_bit(idx, &flags, __SD_FLAG_CNT) {
- char *name = sd_flag_debug[idx].name;
-
-- len += snprintf(tmp + len, strlen(name) + 2, "%s ", name);
-+ len += snprintf(buf + len, strlen(name) + 2, "%s ", name);
- }
-
-- tmp += *ppos;
-+ tmp = buf + *ppos;
- len -= *ppos;
-
- if (len > *lenp)
-@@ -292,7 +292,7 @@ static int sd_ctl_doflags(struct ctl_table *table, int write,
- *lenp = len;
- *ppos += len;
-
-- kfree(tmp);
-+ kfree(buf);
-
- return 0;
- }
---
-2.35.1
-
+++ /dev/null
-From d023794b6b1646ba127c98be1d86ec0bac984e5c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 17 Aug 2020 12:29:52 +0100
-Subject: sched/debug: Output SD flag names rather than their values
-
-From: Valentin Schneider <valentin.schneider@arm.com>
-
-[ Upstream commit 5b9f8ff7b320a34af3dbcf04edb40d9b04f22f4a ]
-
-Decoding the output of /proc/sys/kernel/sched_domain/cpu*/domain*/flags has
-always been somewhat annoying, as one needs to go fetch the bit -> name
-mapping from the source code itself. This encoding can be saved in a script
-somewhere, but that isn't safe from flags being added, removed or even
-shuffled around.
-
-What matters for debugging purposes is to get *which* flags are set in a
-given domain, their associated value is pretty much meaningless.
-
-Make the sd flags debug file output flag names.
-
-Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
-Link: https://lore.kernel.org/r/20200817113003.20802-7-valentin.schneider@arm.com
-Stable-dep-of: c2e406596571 ("sched/debug: fix dentry leak in update_sched_domain_debugfs")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/sched/debug.c | 56 +++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 55 insertions(+), 1 deletion(-)
-
-diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
-index d5f7fc7099bc..df646776b7f0 100644
---- a/kernel/sched/debug.c
-+++ b/kernel/sched/debug.c
-@@ -243,6 +243,60 @@ set_table_entry(struct ctl_table *entry,
- entry->proc_handler = proc_handler;
- }
-
-+static int sd_ctl_doflags(struct ctl_table *table, int write,
-+ void *buffer, size_t *lenp, loff_t *ppos)
-+{
-+ unsigned long flags = *(unsigned long *)table->data;
-+ size_t data_size = 0;
-+ size_t len = 0;
-+ char *tmp;
-+ int idx;
-+
-+ if (write)
-+ return 0;
-+
-+ for_each_set_bit(idx, &flags, __SD_FLAG_CNT) {
-+ char *name = sd_flag_debug[idx].name;
-+
-+ /* Name plus whitespace */
-+ data_size += strlen(name) + 1;
-+ }
-+
-+ if (*ppos > data_size) {
-+ *lenp = 0;
-+ return 0;
-+ }
-+
-+ tmp = kcalloc(data_size + 1, sizeof(*tmp), GFP_KERNEL);
-+ if (!tmp)
-+ return -ENOMEM;
-+
-+ for_each_set_bit(idx, &flags, __SD_FLAG_CNT) {
-+ char *name = sd_flag_debug[idx].name;
-+
-+ len += snprintf(tmp + len, strlen(name) + 2, "%s ", name);
-+ }
-+
-+ tmp += *ppos;
-+ len -= *ppos;
-+
-+ if (len > *lenp)
-+ len = *lenp;
-+ if (len)
-+ memcpy(buffer, tmp, len);
-+ if (len < *lenp) {
-+ ((char *)buffer)[len] = '\n';
-+ len++;
-+ }
-+
-+ *lenp = len;
-+ *ppos += len;
-+
-+ kfree(tmp);
-+
-+ return 0;
-+}
-+
- static struct ctl_table *
- sd_alloc_ctl_domain_table(struct sched_domain *sd)
- {
-@@ -256,7 +310,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
- set_table_entry(&table[2], "busy_factor", &sd->busy_factor, sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[3], "imbalance_pct", &sd->imbalance_pct, sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[4], "cache_nice_tries", &sd->cache_nice_tries, sizeof(int), 0644, proc_dointvec_minmax);
-- set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, proc_dointvec_minmax);
-+ set_table_entry(&table[5], "flags", &sd->flags, sizeof(int), 0444, sd_ctl_doflags);
- set_table_entry(&table[6], "max_newidle_lb_cost", &sd->max_newidle_lb_cost, sizeof(long), 0644, proc_doulongvec_minmax);
- set_table_entry(&table[7], "name", sd->name, CORENAME_MAX_SIZE, 0444, proc_dostring);
- /* &table[8] is terminator */
---
-2.35.1
-