aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c125
1 files changed, 99 insertions, 26 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 74f5b580fe34..75b22e22a72c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -136,7 +136,6 @@ static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
136/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ 136/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
137static int maxolduid = 65535; 137static int maxolduid = 65535;
138static int minolduid; 138static int minolduid;
139static int min_percpu_pagelist_fract = 8;
140 139
141static int ngroups_max = NGROUPS_MAX; 140static int ngroups_max = NGROUPS_MAX;
142static const int cap_last_cap = CAP_LAST_CAP; 141static const int cap_last_cap = CAP_LAST_CAP;
@@ -152,10 +151,6 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
152#ifdef CONFIG_SPARC 151#ifdef CONFIG_SPARC
153#endif 152#endif
154 153
155#ifdef CONFIG_SPARC64
156extern int sysctl_tsb_ratio;
157#endif
158
159#ifdef __hppa__ 154#ifdef __hppa__
160extern int pwrsw_enabled; 155extern int pwrsw_enabled;
161#endif 156#endif
@@ -173,6 +168,13 @@ extern int no_unaligned_warning;
173#endif 168#endif
174 169
175#ifdef CONFIG_PROC_SYSCTL 170#ifdef CONFIG_PROC_SYSCTL
171
172#define SYSCTL_WRITES_LEGACY -1
173#define SYSCTL_WRITES_WARN 0
174#define SYSCTL_WRITES_STRICT 1
175
176static int sysctl_writes_strict = SYSCTL_WRITES_WARN;
177
176static int proc_do_cad_pid(struct ctl_table *table, int write, 178static int proc_do_cad_pid(struct ctl_table *table, int write,
177 void __user *buffer, size_t *lenp, loff_t *ppos); 179 void __user *buffer, size_t *lenp, loff_t *ppos);
178static int proc_taint(struct ctl_table *table, int write, 180static int proc_taint(struct ctl_table *table, int write,
@@ -195,7 +197,7 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
195/* Note: sysrq code uses it's own private copy */ 197/* Note: sysrq code uses it's own private copy */
196static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE; 198static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
197 199
198static int sysrq_sysctl_handler(ctl_table *table, int write, 200static int sysrq_sysctl_handler(struct ctl_table *table, int write,
199 void __user *buffer, size_t *lenp, 201 void __user *buffer, size_t *lenp,
200 loff_t *ppos) 202 loff_t *ppos)
201{ 203{
@@ -495,6 +497,15 @@ static struct ctl_table kern_table[] = {
495 .mode = 0644, 497 .mode = 0644,
496 .proc_handler = proc_taint, 498 .proc_handler = proc_taint,
497 }, 499 },
500 {
501 .procname = "sysctl_writes_strict",
502 .data = &sysctl_writes_strict,
503 .maxlen = sizeof(int),
504 .mode = 0644,
505 .proc_handler = proc_dointvec_minmax,
506 .extra1 = &neg_one,
507 .extra2 = &one,
508 },
498#endif 509#endif
499#ifdef CONFIG_LATENCYTOP 510#ifdef CONFIG_LATENCYTOP
500 { 511 {
@@ -643,7 +654,7 @@ static struct ctl_table kern_table[] = {
643 .extra2 = &one, 654 .extra2 = &one,
644 }, 655 },
645#endif 656#endif
646 657#ifdef CONFIG_UEVENT_HELPER
647 { 658 {
648 .procname = "hotplug", 659 .procname = "hotplug",
649 .data = &uevent_helper, 660 .data = &uevent_helper,
@@ -651,7 +662,7 @@ static struct ctl_table kern_table[] = {
651 .mode = 0644, 662 .mode = 0644,
652 .proc_handler = proc_dostring, 663 .proc_handler = proc_dostring,
653 }, 664 },
654 665#endif
655#ifdef CONFIG_CHR_DEV_SG 666#ifdef CONFIG_CHR_DEV_SG
656 { 667 {
657 .procname = "sg-big-buff", 668 .procname = "sg-big-buff",
@@ -849,6 +860,17 @@ static struct ctl_table kern_table[] = {
849 .extra1 = &zero, 860 .extra1 = &zero,
850 .extra2 = &one, 861 .extra2 = &one,
851 }, 862 },
863#ifdef CONFIG_SMP
864 {
865 .procname = "softlockup_all_cpu_backtrace",
866 .data = &sysctl_softlockup_all_cpu_backtrace,
867 .maxlen = sizeof(int),
868 .mode = 0644,
869 .proc_handler = proc_dointvec_minmax,
870 .extra1 = &zero,
871 .extra2 = &one,
872 },
873#endif /* CONFIG_SMP */
852 { 874 {
853 .procname = "nmi_watchdog", 875 .procname = "nmi_watchdog",
854 .data = &watchdog_user_enabled, 876 .data = &watchdog_user_enabled,
@@ -1305,7 +1327,7 @@ static struct ctl_table vm_table[] = {
1305 .maxlen = sizeof(percpu_pagelist_fraction), 1327 .maxlen = sizeof(percpu_pagelist_fraction),
1306 .mode = 0644, 1328 .mode = 0644,
1307 .proc_handler = percpu_pagelist_fraction_sysctl_handler, 1329 .proc_handler = percpu_pagelist_fraction_sysctl_handler,
1308 .extra1 = &min_percpu_pagelist_fract, 1330 .extra1 = &zero,
1309 }, 1331 },
1310#ifdef CONFIG_MMU 1332#ifdef CONFIG_MMU
1311 { 1333 {
@@ -1418,8 +1440,13 @@ static struct ctl_table vm_table[] = {
1418 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) 1440 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
1419 { 1441 {
1420 .procname = "vdso_enabled", 1442 .procname = "vdso_enabled",
1443#ifdef CONFIG_X86_32
1444 .data = &vdso32_enabled,
1445 .maxlen = sizeof(vdso32_enabled),
1446#else
1421 .data = &vdso_enabled, 1447 .data = &vdso_enabled,
1422 .maxlen = sizeof(vdso_enabled), 1448 .maxlen = sizeof(vdso_enabled),
1449#endif
1423 .mode = 0644, 1450 .mode = 0644,
1424 .proc_handler = proc_dointvec, 1451 .proc_handler = proc_dointvec,
1425 .extra1 = &zero, 1452 .extra1 = &zero,
@@ -1698,8 +1725,8 @@ int __init sysctl_init(void)
1698 1725
1699#ifdef CONFIG_PROC_SYSCTL 1726#ifdef CONFIG_PROC_SYSCTL
1700 1727
1701static int _proc_do_string(void* data, int maxlen, int write, 1728static int _proc_do_string(char *data, int maxlen, int write,
1702 void __user *buffer, 1729 char __user *buffer,
1703 size_t *lenp, loff_t *ppos) 1730 size_t *lenp, loff_t *ppos)
1704{ 1731{
1705 size_t len; 1732 size_t len;
@@ -1712,21 +1739,30 @@ static int _proc_do_string(void* data, int maxlen, int write,
1712 } 1739 }
1713 1740
1714 if (write) { 1741 if (write) {
1715 len = 0; 1742 if (sysctl_writes_strict == SYSCTL_WRITES_STRICT) {
1743 /* Only continue writes not past the end of buffer. */
1744 len = strlen(data);
1745 if (len > maxlen - 1)
1746 len = maxlen - 1;
1747
1748 if (*ppos > len)
1749 return 0;
1750 len = *ppos;
1751 } else {
1752 /* Start writing from beginning of buffer. */
1753 len = 0;
1754 }
1755
1756 *ppos += *lenp;
1716 p = buffer; 1757 p = buffer;
1717 while (len < *lenp) { 1758 while ((p - buffer) < *lenp && len < maxlen - 1) {
1718 if (get_user(c, p++)) 1759 if (get_user(c, p++))
1719 return -EFAULT; 1760 return -EFAULT;
1720 if (c == 0 || c == '\n') 1761 if (c == 0 || c == '\n')
1721 break; 1762 break;
1722 len++; 1763 data[len++] = c;
1723 } 1764 }
1724 if (len >= maxlen) 1765 data[len] = 0;
1725 len = maxlen-1;
1726 if(copy_from_user(data, buffer, len))
1727 return -EFAULT;
1728 ((char *) data)[len] = 0;
1729 *ppos += *lenp;
1730 } else { 1766 } else {
1731 len = strlen(data); 1767 len = strlen(data);
1732 if (len > maxlen) 1768 if (len > maxlen)
@@ -1743,10 +1779,10 @@ static int _proc_do_string(void* data, int maxlen, int write,
1743 if (len > *lenp) 1779 if (len > *lenp)
1744 len = *lenp; 1780 len = *lenp;
1745 if (len) 1781 if (len)
1746 if(copy_to_user(buffer, data, len)) 1782 if (copy_to_user(buffer, data, len))
1747 return -EFAULT; 1783 return -EFAULT;
1748 if (len < *lenp) { 1784 if (len < *lenp) {
1749 if(put_user('\n', ((char __user *) buffer) + len)) 1785 if (put_user('\n', buffer + len))
1750 return -EFAULT; 1786 return -EFAULT;
1751 len++; 1787 len++;
1752 } 1788 }
@@ -1756,6 +1792,14 @@ static int _proc_do_string(void* data, int maxlen, int write,
1756 return 0; 1792 return 0;
1757} 1793}
1758 1794
1795static void warn_sysctl_write(struct ctl_table *table)
1796{
1797 pr_warn_once("%s wrote to %s when file position was not 0!\n"
1798 "This will not be supported in the future. To silence this\n"
1799 "warning, set kernel.sysctl_writes_strict = -1\n",
1800 current->comm, table->procname);
1801}
1802
1759/** 1803/**
1760 * proc_dostring - read a string sysctl 1804 * proc_dostring - read a string sysctl
1761 * @table: the sysctl table 1805 * @table: the sysctl table
@@ -1776,8 +1820,11 @@ static int _proc_do_string(void* data, int maxlen, int write,
1776int proc_dostring(struct ctl_table *table, int write, 1820int proc_dostring(struct ctl_table *table, int write,
1777 void __user *buffer, size_t *lenp, loff_t *ppos) 1821 void __user *buffer, size_t *lenp, loff_t *ppos)
1778{ 1822{
1779 return _proc_do_string(table->data, table->maxlen, write, 1823 if (write && *ppos && sysctl_writes_strict == SYSCTL_WRITES_WARN)
1780 buffer, lenp, ppos); 1824 warn_sysctl_write(table);
1825
1826 return _proc_do_string((char *)(table->data), table->maxlen, write,
1827 (char __user *)buffer, lenp, ppos);
1781} 1828}
1782 1829
1783static size_t proc_skip_spaces(char **buf) 1830static size_t proc_skip_spaces(char **buf)
@@ -1951,6 +1998,18 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
1951 conv = do_proc_dointvec_conv; 1998 conv = do_proc_dointvec_conv;
1952 1999
1953 if (write) { 2000 if (write) {
2001 if (*ppos) {
2002 switch (sysctl_writes_strict) {
2003 case SYSCTL_WRITES_STRICT:
2004 goto out;
2005 case SYSCTL_WRITES_WARN:
2006 warn_sysctl_write(table);
2007 break;
2008 default:
2009 break;
2010 }
2011 }
2012
1954 if (left > PAGE_SIZE - 1) 2013 if (left > PAGE_SIZE - 1)
1955 left = PAGE_SIZE - 1; 2014 left = PAGE_SIZE - 1;
1956 page = __get_free_page(GFP_TEMPORARY); 2015 page = __get_free_page(GFP_TEMPORARY);
@@ -2008,6 +2067,7 @@ free:
2008 return err ? : -EINVAL; 2067 return err ? : -EINVAL;
2009 } 2068 }
2010 *lenp -= left; 2069 *lenp -= left;
2070out:
2011 *ppos += *lenp; 2071 *ppos += *lenp;
2012 return err; 2072 return err;
2013} 2073}
@@ -2200,6 +2260,18 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
2200 left = *lenp; 2260 left = *lenp;
2201 2261
2202 if (write) { 2262 if (write) {
2263 if (*ppos) {
2264 switch (sysctl_writes_strict) {
2265 case SYSCTL_WRITES_STRICT:
2266 goto out;
2267 case SYSCTL_WRITES_WARN:
2268 warn_sysctl_write(table);
2269 break;
2270 default:
2271 break;
2272 }
2273 }
2274
2203 if (left > PAGE_SIZE - 1) 2275 if (left > PAGE_SIZE - 1)
2204 left = PAGE_SIZE - 1; 2276 left = PAGE_SIZE - 1;
2205 page = __get_free_page(GFP_TEMPORARY); 2277 page = __get_free_page(GFP_TEMPORARY);
@@ -2255,6 +2327,7 @@ free:
2255 return err ? : -EINVAL; 2327 return err ? : -EINVAL;
2256 } 2328 }
2257 *lenp -= left; 2329 *lenp -= left;
2330out:
2258 *ppos += *lenp; 2331 *ppos += *lenp;
2259 return err; 2332 return err;
2260} 2333}
@@ -2501,11 +2574,11 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
2501 bool first = 1; 2574 bool first = 1;
2502 size_t left = *lenp; 2575 size_t left = *lenp;
2503 unsigned long bitmap_len = table->maxlen; 2576 unsigned long bitmap_len = table->maxlen;
2504 unsigned long *bitmap = (unsigned long *) table->data; 2577 unsigned long *bitmap = *(unsigned long **) table->data;
2505 unsigned long *tmp_bitmap = NULL; 2578 unsigned long *tmp_bitmap = NULL;
2506 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c; 2579 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
2507 2580
2508 if (!bitmap_len || !left || (*ppos && !write)) { 2581 if (!bitmap || !bitmap_len || !left || (*ppos && !write)) {
2509 *lenp = 0; 2582 *lenp = 0;
2510 return 0; 2583 return 0;
2511 } 2584 }