aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 0f1bd83db985..c0bb32414b17 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -117,6 +117,7 @@ static int neg_one = -1;
117static int zero; 117static int zero;
118static int __maybe_unused one = 1; 118static int __maybe_unused one = 1;
119static int __maybe_unused two = 2; 119static int __maybe_unused two = 2;
120static int __maybe_unused three = 3;
120static unsigned long one_ul = 1; 121static unsigned long one_ul = 1;
121static int one_hundred = 100; 122static int one_hundred = 100;
122#ifdef CONFIG_PRINTK 123#ifdef CONFIG_PRINTK
@@ -169,6 +170,11 @@ static int proc_taint(struct ctl_table *table, int write,
169 void __user *buffer, size_t *lenp, loff_t *ppos); 170 void __user *buffer, size_t *lenp, loff_t *ppos);
170#endif 171#endif
171 172
173#ifdef CONFIG_PRINTK
174static int proc_dmesg_restrict(struct ctl_table *table, int write,
175 void __user *buffer, size_t *lenp, loff_t *ppos);
176#endif
177
172#ifdef CONFIG_MAGIC_SYSRQ 178#ifdef CONFIG_MAGIC_SYSRQ
173/* Note: sysrq code uses it's own private copy */ 179/* Note: sysrq code uses it's own private copy */
174static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; 180static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
@@ -194,9 +200,9 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
194static struct ctl_table root_table[]; 200static struct ctl_table root_table[];
195static struct ctl_table_root sysctl_table_root; 201static struct ctl_table_root sysctl_table_root;
196static struct ctl_table_header root_table_header = { 202static struct ctl_table_header root_table_header = {
197 .count = 1, 203 {{.count = 1,
198 .ctl_table = root_table, 204 .ctl_table = root_table,
199 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), 205 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),}},
200 .root = &sysctl_table_root, 206 .root = &sysctl_table_root,
201 .set = &sysctl_table_root.default_set, 207 .set = &sysctl_table_root.default_set,
202}; 208};
@@ -361,20 +367,13 @@ static struct ctl_table kern_table[] = {
361 .mode = 0644, 367 .mode = 0644,
362 .proc_handler = sched_rt_handler, 368 .proc_handler = sched_rt_handler,
363 }, 369 },
364 {
365 .procname = "sched_compat_yield",
366 .data = &sysctl_sched_compat_yield,
367 .maxlen = sizeof(unsigned int),
368 .mode = 0644,
369 .proc_handler = proc_dointvec,
370 },
371#ifdef CONFIG_SCHED_AUTOGROUP 370#ifdef CONFIG_SCHED_AUTOGROUP
372 { 371 {
373 .procname = "sched_autogroup_enabled", 372 .procname = "sched_autogroup_enabled",
374 .data = &sysctl_sched_autogroup_enabled, 373 .data = &sysctl_sched_autogroup_enabled,
375 .maxlen = sizeof(unsigned int), 374 .maxlen = sizeof(unsigned int),
376 .mode = 0644, 375 .mode = 0644,
377 .proc_handler = proc_dointvec, 376 .proc_handler = proc_dointvec_minmax,
378 .extra1 = &zero, 377 .extra1 = &zero,
379 .extra2 = &one, 378 .extra2 = &one,
380 }, 379 },
@@ -713,7 +712,7 @@ static struct ctl_table kern_table[] = {
713 .data = &kptr_restrict, 712 .data = &kptr_restrict,
714 .maxlen = sizeof(int), 713 .maxlen = sizeof(int),
715 .mode = 0644, 714 .mode = 0644,
716 .proc_handler = proc_dointvec_minmax, 715 .proc_handler = proc_dmesg_restrict,
717 .extra1 = &zero, 716 .extra1 = &zero,
718 .extra2 = &two, 717 .extra2 = &two,
719 }, 718 },
@@ -948,7 +947,7 @@ static struct ctl_table kern_table[] = {
948 .data = &sysctl_perf_event_sample_rate, 947 .data = &sysctl_perf_event_sample_rate,
949 .maxlen = sizeof(sysctl_perf_event_sample_rate), 948 .maxlen = sizeof(sysctl_perf_event_sample_rate),
950 .mode = 0644, 949 .mode = 0644,
951 .proc_handler = proc_dointvec, 950 .proc_handler = perf_proc_update_handler,
952 }, 951 },
953#endif 952#endif
954#ifdef CONFIG_KMEMCHECK 953#ifdef CONFIG_KMEMCHECK
@@ -978,14 +977,18 @@ static struct ctl_table vm_table[] = {
978 .data = &sysctl_overcommit_memory, 977 .data = &sysctl_overcommit_memory,
979 .maxlen = sizeof(sysctl_overcommit_memory), 978 .maxlen = sizeof(sysctl_overcommit_memory),
980 .mode = 0644, 979 .mode = 0644,
981 .proc_handler = proc_dointvec, 980 .proc_handler = proc_dointvec_minmax,
981 .extra1 = &zero,
982 .extra2 = &two,
982 }, 983 },
983 { 984 {
984 .procname = "panic_on_oom", 985 .procname = "panic_on_oom",
985 .data = &sysctl_panic_on_oom, 986 .data = &sysctl_panic_on_oom,
986 .maxlen = sizeof(sysctl_panic_on_oom), 987 .maxlen = sizeof(sysctl_panic_on_oom),
987 .mode = 0644, 988 .mode = 0644,
988 .proc_handler = proc_dointvec, 989 .proc_handler = proc_dointvec_minmax,
990 .extra1 = &zero,
991 .extra2 = &two,
989 }, 992 },
990 { 993 {
991 .procname = "oom_kill_allocating_task", 994 .procname = "oom_kill_allocating_task",
@@ -1013,7 +1016,8 @@ static struct ctl_table vm_table[] = {
1013 .data = &page_cluster, 1016 .data = &page_cluster,
1014 .maxlen = sizeof(int), 1017 .maxlen = sizeof(int),
1015 .mode = 0644, 1018 .mode = 0644,
1016 .proc_handler = proc_dointvec, 1019 .proc_handler = proc_dointvec_minmax,
1020 .extra1 = &zero,
1017 }, 1021 },
1018 { 1022 {
1019 .procname = "dirty_background_ratio", 1023 .procname = "dirty_background_ratio",
@@ -1061,7 +1065,8 @@ static struct ctl_table vm_table[] = {
1061 .data = &dirty_expire_interval, 1065 .data = &dirty_expire_interval,
1062 .maxlen = sizeof(dirty_expire_interval), 1066 .maxlen = sizeof(dirty_expire_interval),
1063 .mode = 0644, 1067 .mode = 0644,
1064 .proc_handler = proc_dointvec, 1068 .proc_handler = proc_dointvec_minmax,
1069 .extra1 = &zero,
1065 }, 1070 },
1066 { 1071 {
1067 .procname = "nr_pdflush_threads", 1072 .procname = "nr_pdflush_threads",
@@ -1137,6 +1142,8 @@ static struct ctl_table vm_table[] = {
1137 .maxlen = sizeof(int), 1142 .maxlen = sizeof(int),
1138 .mode = 0644, 1143 .mode = 0644,
1139 .proc_handler = drop_caches_sysctl_handler, 1144 .proc_handler = drop_caches_sysctl_handler,
1145 .extra1 = &one,
1146 .extra2 = &three,
1140 }, 1147 },
1141#ifdef CONFIG_COMPACTION 1148#ifdef CONFIG_COMPACTION
1142 { 1149 {
@@ -1567,11 +1574,16 @@ void sysctl_head_get(struct ctl_table_header *head)
1567 spin_unlock(&sysctl_lock); 1574 spin_unlock(&sysctl_lock);
1568} 1575}
1569 1576
1577static void free_head(struct rcu_head *rcu)
1578{
1579 kfree(container_of(rcu, struct ctl_table_header, rcu));
1580}
1581
1570void sysctl_head_put(struct ctl_table_header *head) 1582void sysctl_head_put(struct ctl_table_header *head)
1571{ 1583{
1572 spin_lock(&sysctl_lock); 1584 spin_lock(&sysctl_lock);
1573 if (!--head->count) 1585 if (!--head->count)
1574 kfree(head); 1586 call_rcu(&head->rcu, free_head);
1575 spin_unlock(&sysctl_lock); 1587 spin_unlock(&sysctl_lock);
1576} 1588}
1577 1589
@@ -1685,13 +1697,8 @@ static int test_perm(int mode, int op)
1685 1697
1686int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) 1698int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
1687{ 1699{
1688 int error;
1689 int mode; 1700 int mode;
1690 1701
1691 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
1692 if (error)
1693 return error;
1694
1695 if (root->permissions) 1702 if (root->permissions)
1696 mode = root->permissions(root, current->nsproxy, table); 1703 mode = root->permissions(root, current->nsproxy, table);
1697 else 1704 else
@@ -1948,10 +1955,10 @@ void unregister_sysctl_table(struct ctl_table_header * header)
1948 start_unregistering(header); 1955 start_unregistering(header);
1949 if (!--header->parent->count) { 1956 if (!--header->parent->count) {
1950 WARN_ON(1); 1957 WARN_ON(1);
1951 kfree(header->parent); 1958 call_rcu(&header->parent->rcu, free_head);
1952 } 1959 }
1953 if (!--header->count) 1960 if (!--header->count)
1954 kfree(header); 1961 call_rcu(&header->rcu, free_head);
1955 spin_unlock(&sysctl_lock); 1962 spin_unlock(&sysctl_lock);
1956} 1963}
1957 1964
@@ -2392,6 +2399,17 @@ static int proc_taint(struct ctl_table *table, int write,
2392 return err; 2399 return err;
2393} 2400}
2394 2401
2402#ifdef CONFIG_PRINTK
2403static int proc_dmesg_restrict(struct ctl_table *table, int write,
2404 void __user *buffer, size_t *lenp, loff_t *ppos)
2405{
2406 if (write && !capable(CAP_SYS_ADMIN))
2407 return -EPERM;
2408
2409 return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
2410}
2411#endif
2412
2395struct do_proc_dointvec_minmax_conv_param { 2413struct do_proc_dointvec_minmax_conv_param {
2396 int *min; 2414 int *min;
2397 int *max; 2415 int *max;