Skip to content

Commit 201c373

Browse files
Namhyung KimIngo Molnar
authored andcommitted
sched/debug: Limit sd->*_idx range on sysctl
Various sd->*_idx's are used for refering the rq's load average table when selecting a cpu to run. However they can be set to any number with sysctl knobs so that it can crash the kernel if something bad is given. Fix it by limiting them into the actual range. Signed-off-by: Namhyung Kim <[email protected]> Signed-off-by: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent c751134 commit 201c373

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

kernel/sched/core.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4896,16 +4896,25 @@ static void sd_free_ctl_entry(struct ctl_table **tablep)
48964896
*tablep = NULL;
48974897
}
48984898

4899+
static int min_load_idx = 0;
4900+
static int max_load_idx = CPU_LOAD_IDX_MAX;
4901+
48994902
static void
49004903
set_table_entry(struct ctl_table *entry,
49014904
const char *procname, void *data, int maxlen,
4902-
umode_t mode, proc_handler *proc_handler)
4905+
umode_t mode, proc_handler *proc_handler,
4906+
bool load_idx)
49034907
{
49044908
entry->procname = procname;
49054909
entry->data = data;
49064910
entry->maxlen = maxlen;
49074911
entry->mode = mode;
49084912
entry->proc_handler = proc_handler;
4913+
4914+
if (load_idx) {
4915+
entry->extra1 = &min_load_idx;
4916+
entry->extra2 = &max_load_idx;
4917+
}
49094918
}
49104919

49114920
static struct ctl_table *
@@ -4917,30 +4926,30 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
49174926
return NULL;
49184927

49194928
set_table_entry(&table[0], "min_interval", &sd->min_interval,
4920-
sizeof(long), 0644, proc_doulongvec_minmax);
4929+
sizeof(long), 0644, proc_doulongvec_minmax, false);
49214930
set_table_entry(&table[1], "max_interval", &sd->max_interval,
4922-
sizeof(long), 0644, proc_doulongvec_minmax);
4931+
sizeof(long), 0644, proc_doulongvec_minmax, false);
49234932
set_table_entry(&table[2], "busy_idx", &sd->busy_idx,
4924-
sizeof(int), 0644, proc_dointvec_minmax);
4933+
sizeof(int), 0644, proc_dointvec_minmax, true);
49254934
set_table_entry(&table[3], "idle_idx", &sd->idle_idx,
4926-
sizeof(int), 0644, proc_dointvec_minmax);
4935+
sizeof(int), 0644, proc_dointvec_minmax, true);
49274936
set_table_entry(&table[4], "newidle_idx", &sd->newidle_idx,
4928-
sizeof(int), 0644, proc_dointvec_minmax);
4937+
sizeof(int), 0644, proc_dointvec_minmax, true);
49294938
set_table_entry(&table[5], "wake_idx", &sd->wake_idx,
4930-
sizeof(int), 0644, proc_dointvec_minmax);
4939+
sizeof(int), 0644, proc_dointvec_minmax, true);
49314940
set_table_entry(&table[6], "forkexec_idx", &sd->forkexec_idx,
4932-
sizeof(int), 0644, proc_dointvec_minmax);
4941+
sizeof(int), 0644, proc_dointvec_minmax, true);
49334942
set_table_entry(&table[7], "busy_factor", &sd->busy_factor,
4934-
sizeof(int), 0644, proc_dointvec_minmax);
4943+
sizeof(int), 0644, proc_dointvec_minmax, false);
49354944
set_table_entry(&table[8], "imbalance_pct", &sd->imbalance_pct,
4936-
sizeof(int), 0644, proc_dointvec_minmax);
4945+
sizeof(int), 0644, proc_dointvec_minmax, false);
49374946
set_table_entry(&table[9], "cache_nice_tries",
49384947
&sd->cache_nice_tries,
4939-
sizeof(int), 0644, proc_dointvec_minmax);
4948+
sizeof(int), 0644, proc_dointvec_minmax, false);
49404949
set_table_entry(&table[10], "flags", &sd->flags,
4941-
sizeof(int), 0644, proc_dointvec_minmax);
4950+
sizeof(int), 0644, proc_dointvec_minmax, false);
49424951
set_table_entry(&table[11], "name", sd->name,
4943-
CORENAME_MAX_SIZE, 0444, proc_dostring);
4952+
CORENAME_MAX_SIZE, 0444, proc_dostring, false);
49444953
/* &table[12] is terminator */
49454954

49464955
return table;

0 commit comments

Comments
 (0)