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