diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0f1bd83db985..4fc92445a29c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/kprobes.h> | 56 | #include <linux/kprobes.h> |
57 | #include <linux/pipe_fs_i.h> | 57 | #include <linux/pipe_fs_i.h> |
58 | #include <linux/oom.h> | 58 | #include <linux/oom.h> |
59 | #include <linux/kmod.h> | ||
59 | 60 | ||
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | #include <asm/processor.h> | 62 | #include <asm/processor.h> |
@@ -117,6 +118,7 @@ static int neg_one = -1; | |||
117 | static int zero; | 118 | static int zero; |
118 | static int __maybe_unused one = 1; | 119 | static int __maybe_unused one = 1; |
119 | static int __maybe_unused two = 2; | 120 | static int __maybe_unused two = 2; |
121 | static int __maybe_unused three = 3; | ||
120 | static unsigned long one_ul = 1; | 122 | static unsigned long one_ul = 1; |
121 | static int one_hundred = 100; | 123 | static int one_hundred = 100; |
122 | #ifdef CONFIG_PRINTK | 124 | #ifdef CONFIG_PRINTK |
@@ -169,6 +171,11 @@ static int proc_taint(struct ctl_table *table, int write, | |||
169 | void __user *buffer, size_t *lenp, loff_t *ppos); | 171 | void __user *buffer, size_t *lenp, loff_t *ppos); |
170 | #endif | 172 | #endif |
171 | 173 | ||
174 | #ifdef CONFIG_PRINTK | ||
175 | static int proc_dmesg_restrict(struct ctl_table *table, int write, | ||
176 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
177 | #endif | ||
178 | |||
172 | #ifdef CONFIG_MAGIC_SYSRQ | 179 | #ifdef CONFIG_MAGIC_SYSRQ |
173 | /* Note: sysrq code uses it's own private copy */ | 180 | /* Note: sysrq code uses it's own private copy */ |
174 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; | 181 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; |
@@ -194,9 +201,9 @@ static int sysrq_sysctl_handler(ctl_table *table, int write, | |||
194 | static struct ctl_table root_table[]; | 201 | static struct ctl_table root_table[]; |
195 | static struct ctl_table_root sysctl_table_root; | 202 | static struct ctl_table_root sysctl_table_root; |
196 | static struct ctl_table_header root_table_header = { | 203 | static struct ctl_table_header root_table_header = { |
197 | .count = 1, | 204 | {{.count = 1, |
198 | .ctl_table = root_table, | 205 | .ctl_table = root_table, |
199 | .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), | 206 | .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),}}, |
200 | .root = &sysctl_table_root, | 207 | .root = &sysctl_table_root, |
201 | .set = &sysctl_table_root.default_set, | 208 | .set = &sysctl_table_root.default_set, |
202 | }; | 209 | }; |
@@ -361,20 +368,13 @@ static struct ctl_table kern_table[] = { | |||
361 | .mode = 0644, | 368 | .mode = 0644, |
362 | .proc_handler = sched_rt_handler, | 369 | .proc_handler = sched_rt_handler, |
363 | }, | 370 | }, |
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 | 371 | #ifdef CONFIG_SCHED_AUTOGROUP |
372 | { | 372 | { |
373 | .procname = "sched_autogroup_enabled", | 373 | .procname = "sched_autogroup_enabled", |
374 | .data = &sysctl_sched_autogroup_enabled, | 374 | .data = &sysctl_sched_autogroup_enabled, |
375 | .maxlen = sizeof(unsigned int), | 375 | .maxlen = sizeof(unsigned int), |
376 | .mode = 0644, | 376 | .mode = 0644, |
377 | .proc_handler = proc_dointvec, | 377 | .proc_handler = proc_dointvec_minmax, |
378 | .extra1 = &zero, | 378 | .extra1 = &zero, |
379 | .extra2 = &one, | 379 | .extra2 = &one, |
380 | }, | 380 | }, |
@@ -617,6 +617,11 @@ static struct ctl_table kern_table[] = { | |||
617 | .child = random_table, | 617 | .child = random_table, |
618 | }, | 618 | }, |
619 | { | 619 | { |
620 | .procname = "usermodehelper", | ||
621 | .mode = 0555, | ||
622 | .child = usermodehelper_table, | ||
623 | }, | ||
624 | { | ||
620 | .procname = "overflowuid", | 625 | .procname = "overflowuid", |
621 | .data = &overflowuid, | 626 | .data = &overflowuid, |
622 | .maxlen = sizeof(int), | 627 | .maxlen = sizeof(int), |
@@ -713,7 +718,7 @@ static struct ctl_table kern_table[] = { | |||
713 | .data = &kptr_restrict, | 718 | .data = &kptr_restrict, |
714 | .maxlen = sizeof(int), | 719 | .maxlen = sizeof(int), |
715 | .mode = 0644, | 720 | .mode = 0644, |
716 | .proc_handler = proc_dointvec_minmax, | 721 | .proc_handler = proc_dmesg_restrict, |
717 | .extra1 = &zero, | 722 | .extra1 = &zero, |
718 | .extra2 = &two, | 723 | .extra2 = &two, |
719 | }, | 724 | }, |
@@ -731,14 +736,16 @@ static struct ctl_table kern_table[] = { | |||
731 | .data = &watchdog_enabled, | 736 | .data = &watchdog_enabled, |
732 | .maxlen = sizeof (int), | 737 | .maxlen = sizeof (int), |
733 | .mode = 0644, | 738 | .mode = 0644, |
734 | .proc_handler = proc_dowatchdog_enabled, | 739 | .proc_handler = proc_dowatchdog, |
740 | .extra1 = &zero, | ||
741 | .extra2 = &one, | ||
735 | }, | 742 | }, |
736 | { | 743 | { |
737 | .procname = "watchdog_thresh", | 744 | .procname = "watchdog_thresh", |
738 | .data = &softlockup_thresh, | 745 | .data = &watchdog_thresh, |
739 | .maxlen = sizeof(int), | 746 | .maxlen = sizeof(int), |
740 | .mode = 0644, | 747 | .mode = 0644, |
741 | .proc_handler = proc_dowatchdog_thresh, | 748 | .proc_handler = proc_dowatchdog, |
742 | .extra1 = &neg_one, | 749 | .extra1 = &neg_one, |
743 | .extra2 = &sixty, | 750 | .extra2 = &sixty, |
744 | }, | 751 | }, |
@@ -756,7 +763,9 @@ static struct ctl_table kern_table[] = { | |||
756 | .data = &watchdog_enabled, | 763 | .data = &watchdog_enabled, |
757 | .maxlen = sizeof (int), | 764 | .maxlen = sizeof (int), |
758 | .mode = 0644, | 765 | .mode = 0644, |
759 | .proc_handler = proc_dowatchdog_enabled, | 766 | .proc_handler = proc_dowatchdog, |
767 | .extra1 = &zero, | ||
768 | .extra2 = &one, | ||
760 | }, | 769 | }, |
761 | #endif | 770 | #endif |
762 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) | 771 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) |
@@ -948,7 +957,7 @@ static struct ctl_table kern_table[] = { | |||
948 | .data = &sysctl_perf_event_sample_rate, | 957 | .data = &sysctl_perf_event_sample_rate, |
949 | .maxlen = sizeof(sysctl_perf_event_sample_rate), | 958 | .maxlen = sizeof(sysctl_perf_event_sample_rate), |
950 | .mode = 0644, | 959 | .mode = 0644, |
951 | .proc_handler = proc_dointvec, | 960 | .proc_handler = perf_proc_update_handler, |
952 | }, | 961 | }, |
953 | #endif | 962 | #endif |
954 | #ifdef CONFIG_KMEMCHECK | 963 | #ifdef CONFIG_KMEMCHECK |
@@ -978,14 +987,18 @@ static struct ctl_table vm_table[] = { | |||
978 | .data = &sysctl_overcommit_memory, | 987 | .data = &sysctl_overcommit_memory, |
979 | .maxlen = sizeof(sysctl_overcommit_memory), | 988 | .maxlen = sizeof(sysctl_overcommit_memory), |
980 | .mode = 0644, | 989 | .mode = 0644, |
981 | .proc_handler = proc_dointvec, | 990 | .proc_handler = proc_dointvec_minmax, |
991 | .extra1 = &zero, | ||
992 | .extra2 = &two, | ||
982 | }, | 993 | }, |
983 | { | 994 | { |
984 | .procname = "panic_on_oom", | 995 | .procname = "panic_on_oom", |
985 | .data = &sysctl_panic_on_oom, | 996 | .data = &sysctl_panic_on_oom, |
986 | .maxlen = sizeof(sysctl_panic_on_oom), | 997 | .maxlen = sizeof(sysctl_panic_on_oom), |
987 | .mode = 0644, | 998 | .mode = 0644, |
988 | .proc_handler = proc_dointvec, | 999 | .proc_handler = proc_dointvec_minmax, |
1000 | .extra1 = &zero, | ||
1001 | .extra2 = &two, | ||
989 | }, | 1002 | }, |
990 | { | 1003 | { |
991 | .procname = "oom_kill_allocating_task", | 1004 | .procname = "oom_kill_allocating_task", |
@@ -1013,7 +1026,8 @@ static struct ctl_table vm_table[] = { | |||
1013 | .data = &page_cluster, | 1026 | .data = &page_cluster, |
1014 | .maxlen = sizeof(int), | 1027 | .maxlen = sizeof(int), |
1015 | .mode = 0644, | 1028 | .mode = 0644, |
1016 | .proc_handler = proc_dointvec, | 1029 | .proc_handler = proc_dointvec_minmax, |
1030 | .extra1 = &zero, | ||
1017 | }, | 1031 | }, |
1018 | { | 1032 | { |
1019 | .procname = "dirty_background_ratio", | 1033 | .procname = "dirty_background_ratio", |
@@ -1061,7 +1075,8 @@ static struct ctl_table vm_table[] = { | |||
1061 | .data = &dirty_expire_interval, | 1075 | .data = &dirty_expire_interval, |
1062 | .maxlen = sizeof(dirty_expire_interval), | 1076 | .maxlen = sizeof(dirty_expire_interval), |
1063 | .mode = 0644, | 1077 | .mode = 0644, |
1064 | .proc_handler = proc_dointvec, | 1078 | .proc_handler = proc_dointvec_minmax, |
1079 | .extra1 = &zero, | ||
1065 | }, | 1080 | }, |
1066 | { | 1081 | { |
1067 | .procname = "nr_pdflush_threads", | 1082 | .procname = "nr_pdflush_threads", |
@@ -1137,6 +1152,8 @@ static struct ctl_table vm_table[] = { | |||
1137 | .maxlen = sizeof(int), | 1152 | .maxlen = sizeof(int), |
1138 | .mode = 0644, | 1153 | .mode = 0644, |
1139 | .proc_handler = drop_caches_sysctl_handler, | 1154 | .proc_handler = drop_caches_sysctl_handler, |
1155 | .extra1 = &one, | ||
1156 | .extra2 = &three, | ||
1140 | }, | 1157 | }, |
1141 | #ifdef CONFIG_COMPACTION | 1158 | #ifdef CONFIG_COMPACTION |
1142 | { | 1159 | { |
@@ -1489,7 +1506,7 @@ static struct ctl_table fs_table[] = { | |||
1489 | 1506 | ||
1490 | static struct ctl_table debug_table[] = { | 1507 | static struct ctl_table debug_table[] = { |
1491 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \ | 1508 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \ |
1492 | defined(CONFIG_S390) | 1509 | defined(CONFIG_S390) || defined(CONFIG_TILE) |
1493 | { | 1510 | { |
1494 | .procname = "exception-trace", | 1511 | .procname = "exception-trace", |
1495 | .data = &show_unhandled_signals, | 1512 | .data = &show_unhandled_signals, |
@@ -1567,11 +1584,16 @@ void sysctl_head_get(struct ctl_table_header *head) | |||
1567 | spin_unlock(&sysctl_lock); | 1584 | spin_unlock(&sysctl_lock); |
1568 | } | 1585 | } |
1569 | 1586 | ||
1587 | static void free_head(struct rcu_head *rcu) | ||
1588 | { | ||
1589 | kfree(container_of(rcu, struct ctl_table_header, rcu)); | ||
1590 | } | ||
1591 | |||
1570 | void sysctl_head_put(struct ctl_table_header *head) | 1592 | void sysctl_head_put(struct ctl_table_header *head) |
1571 | { | 1593 | { |
1572 | spin_lock(&sysctl_lock); | 1594 | spin_lock(&sysctl_lock); |
1573 | if (!--head->count) | 1595 | if (!--head->count) |
1574 | kfree(head); | 1596 | call_rcu(&head->rcu, free_head); |
1575 | spin_unlock(&sysctl_lock); | 1597 | spin_unlock(&sysctl_lock); |
1576 | } | 1598 | } |
1577 | 1599 | ||
@@ -1685,13 +1707,8 @@ static int test_perm(int mode, int op) | |||
1685 | 1707 | ||
1686 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) | 1708 | int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) |
1687 | { | 1709 | { |
1688 | int error; | ||
1689 | int mode; | 1710 | int mode; |
1690 | 1711 | ||
1691 | error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); | ||
1692 | if (error) | ||
1693 | return error; | ||
1694 | |||
1695 | if (root->permissions) | 1712 | if (root->permissions) |
1696 | mode = root->permissions(root, current->nsproxy, table); | 1713 | mode = root->permissions(root, current->nsproxy, table); |
1697 | else | 1714 | else |
@@ -1948,10 +1965,10 @@ void unregister_sysctl_table(struct ctl_table_header * header) | |||
1948 | start_unregistering(header); | 1965 | start_unregistering(header); |
1949 | if (!--header->parent->count) { | 1966 | if (!--header->parent->count) { |
1950 | WARN_ON(1); | 1967 | WARN_ON(1); |
1951 | kfree(header->parent); | 1968 | call_rcu(&header->parent->rcu, free_head); |
1952 | } | 1969 | } |
1953 | if (!--header->count) | 1970 | if (!--header->count) |
1954 | kfree(header); | 1971 | call_rcu(&header->rcu, free_head); |
1955 | spin_unlock(&sysctl_lock); | 1972 | spin_unlock(&sysctl_lock); |
1956 | } | 1973 | } |
1957 | 1974 | ||
@@ -2392,6 +2409,17 @@ static int proc_taint(struct ctl_table *table, int write, | |||
2392 | return err; | 2409 | return err; |
2393 | } | 2410 | } |
2394 | 2411 | ||
2412 | #ifdef CONFIG_PRINTK | ||
2413 | static int proc_dmesg_restrict(struct ctl_table *table, int write, | ||
2414 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2415 | { | ||
2416 | if (write && !capable(CAP_SYS_ADMIN)) | ||
2417 | return -EPERM; | ||
2418 | |||
2419 | return proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
2420 | } | ||
2421 | #endif | ||
2422 | |||
2395 | struct do_proc_dointvec_minmax_conv_param { | 2423 | struct do_proc_dointvec_minmax_conv_param { |
2396 | int *min; | 2424 | int *min; |
2397 | int *max; | 2425 | int *max; |