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; |
