aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c123
1 files changed, 51 insertions, 72 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 50ec0886fa3d..617d41e4d6a0 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -80,7 +80,6 @@ extern int pid_max_min, pid_max_max;
80extern int sysctl_drop_caches; 80extern int sysctl_drop_caches;
81extern int percpu_pagelist_fraction; 81extern int percpu_pagelist_fraction;
82extern int compat_log; 82extern int compat_log;
83extern int maps_protect;
84extern int latencytop_enabled; 83extern int latencytop_enabled;
85extern int sysctl_nr_open_min, sysctl_nr_open_max; 84extern int sysctl_nr_open_min, sysctl_nr_open_max;
86#ifdef CONFIG_RCU_TORTURE_TEST 85#ifdef CONFIG_RCU_TORTURE_TEST
@@ -97,7 +96,7 @@ static int sixty = 60;
97static int neg_one = -1; 96static int neg_one = -1;
98#endif 97#endif
99 98
100#ifdef CONFIG_MMU 99#if defined(CONFIG_MMU) && defined(CONFIG_FILE_LOCKING)
101static int two = 2; 100static int two = 2;
102#endif 101#endif
103 102
@@ -118,10 +117,8 @@ extern char modprobe_path[];
118extern int sg_big_buff; 117extern int sg_big_buff;
119#endif 118#endif
120 119
121#ifdef __sparc__ 120#ifdef CONFIG_SPARC
122extern char reboot_command []; 121#include <asm/system.h>
123extern int stop_a_enabled;
124extern int scons_pwroff;
125#endif 122#endif
126 123
127#ifdef __hppa__ 124#ifdef __hppa__
@@ -152,7 +149,7 @@ extern int max_lock_depth;
152#ifdef CONFIG_PROC_SYSCTL 149#ifdef CONFIG_PROC_SYSCTL
153static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, 150static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
154 void __user *buffer, size_t *lenp, loff_t *ppos); 151 void __user *buffer, size_t *lenp, loff_t *ppos);
155static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, 152static int proc_taint(struct ctl_table *table, int write, struct file *filp,
156 void __user *buffer, size_t *lenp, loff_t *ppos); 153 void __user *buffer, size_t *lenp, loff_t *ppos);
157#endif 154#endif
158 155
@@ -382,10 +379,9 @@ static struct ctl_table kern_table[] = {
382#ifdef CONFIG_PROC_SYSCTL 379#ifdef CONFIG_PROC_SYSCTL
383 { 380 {
384 .procname = "tainted", 381 .procname = "tainted",
385 .data = &tainted, 382 .maxlen = sizeof(long),
386 .maxlen = sizeof(int),
387 .mode = 0644, 383 .mode = 0644,
388 .proc_handler = &proc_dointvec_taint, 384 .proc_handler = &proc_taint,
389 }, 385 },
390#endif 386#endif
391#ifdef CONFIG_LATENCYTOP 387#ifdef CONFIG_LATENCYTOP
@@ -415,7 +411,7 @@ static struct ctl_table kern_table[] = {
415 .mode = 0644, 411 .mode = 0644,
416 .proc_handler = &proc_dointvec, 412 .proc_handler = &proc_dointvec,
417 }, 413 },
418#ifdef __sparc__ 414#ifdef CONFIG_SPARC
419 { 415 {
420 .ctl_name = KERN_SPARC_REBOOT, 416 .ctl_name = KERN_SPARC_REBOOT,
421 .procname = "reboot-cmd", 417 .procname = "reboot-cmd",
@@ -810,16 +806,6 @@ static struct ctl_table kern_table[] = {
810 .proc_handler = &proc_dointvec, 806 .proc_handler = &proc_dointvec,
811 }, 807 },
812#endif 808#endif
813#ifdef CONFIG_PROC_FS
814 {
815 .ctl_name = CTL_UNNUMBERED,
816 .procname = "maps_protect",
817 .data = &maps_protect,
818 .maxlen = sizeof(int),
819 .mode = 0644,
820 .proc_handler = &proc_dointvec,
821 },
822#endif
823 { 809 {
824 .ctl_name = CTL_UNNUMBERED, 810 .ctl_name = CTL_UNNUMBERED,
825 .procname = "poweroff_cmd", 811 .procname = "poweroff_cmd",
@@ -1261,6 +1247,7 @@ static struct ctl_table fs_table[] = {
1261 .extra1 = &minolduid, 1247 .extra1 = &minolduid,
1262 .extra2 = &maxolduid, 1248 .extra2 = &maxolduid,
1263 }, 1249 },
1250#ifdef CONFIG_FILE_LOCKING
1264 { 1251 {
1265 .ctl_name = FS_LEASES, 1252 .ctl_name = FS_LEASES,
1266 .procname = "leases-enable", 1253 .procname = "leases-enable",
@@ -1269,6 +1256,7 @@ static struct ctl_table fs_table[] = {
1269 .mode = 0644, 1256 .mode = 0644,
1270 .proc_handler = &proc_dointvec, 1257 .proc_handler = &proc_dointvec,
1271 }, 1258 },
1259#endif
1272#ifdef CONFIG_DNOTIFY 1260#ifdef CONFIG_DNOTIFY
1273 { 1261 {
1274 .ctl_name = FS_DIR_NOTIFY, 1262 .ctl_name = FS_DIR_NOTIFY,
@@ -1280,6 +1268,7 @@ static struct ctl_table fs_table[] = {
1280 }, 1268 },
1281#endif 1269#endif
1282#ifdef CONFIG_MMU 1270#ifdef CONFIG_MMU
1271#ifdef CONFIG_FILE_LOCKING
1283 { 1272 {
1284 .ctl_name = FS_LEASE_TIME, 1273 .ctl_name = FS_LEASE_TIME,
1285 .procname = "lease-break-time", 1274 .procname = "lease-break-time",
@@ -1291,6 +1280,8 @@ static struct ctl_table fs_table[] = {
1291 .extra1 = &zero, 1280 .extra1 = &zero,
1292 .extra2 = &two, 1281 .extra2 = &two,
1293 }, 1282 },
1283#endif
1284#ifdef CONFIG_AIO
1294 { 1285 {
1295 .procname = "aio-nr", 1286 .procname = "aio-nr",
1296 .data = &aio_nr, 1287 .data = &aio_nr,
@@ -1305,6 +1296,7 @@ static struct ctl_table fs_table[] = {
1305 .mode = 0644, 1296 .mode = 0644,
1306 .proc_handler = &proc_doulongvec_minmax, 1297 .proc_handler = &proc_doulongvec_minmax,
1307 }, 1298 },
1299#endif /* CONFIG_AIO */
1308#ifdef CONFIG_INOTIFY_USER 1300#ifdef CONFIG_INOTIFY_USER
1309 { 1301 {
1310 .ctl_name = FS_INOTIFY, 1302 .ctl_name = FS_INOTIFY,
@@ -1510,7 +1502,6 @@ void register_sysctl_root(struct ctl_table_root *root)
1510/* Perform the actual read/write of a sysctl table entry. */ 1502/* Perform the actual read/write of a sysctl table entry. */
1511static int do_sysctl_strategy(struct ctl_table_root *root, 1503static int do_sysctl_strategy(struct ctl_table_root *root,
1512 struct ctl_table *table, 1504 struct ctl_table *table,
1513 int __user *name, int nlen,
1514 void __user *oldval, size_t __user *oldlenp, 1505 void __user *oldval, size_t __user *oldlenp,
1515 void __user *newval, size_t newlen) 1506 void __user *newval, size_t newlen)
1516{ 1507{
@@ -1524,8 +1515,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
1524 return -EPERM; 1515 return -EPERM;
1525 1516
1526 if (table->strategy) { 1517 if (table->strategy) {
1527 rc = table->strategy(table, name, nlen, oldval, oldlenp, 1518 rc = table->strategy(table, oldval, oldlenp, newval, newlen);
1528 newval, newlen);
1529 if (rc < 0) 1519 if (rc < 0)
1530 return rc; 1520 return rc;
1531 if (rc > 0) 1521 if (rc > 0)
@@ -1535,8 +1525,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
1535 /* If there is no strategy routine, or if the strategy returns 1525 /* If there is no strategy routine, or if the strategy returns
1536 * zero, proceed with automatic r/w */ 1526 * zero, proceed with automatic r/w */
1537 if (table->data && table->maxlen) { 1527 if (table->data && table->maxlen) {
1538 rc = sysctl_data(table, name, nlen, oldval, oldlenp, 1528 rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
1539 newval, newlen);
1540 if (rc < 0) 1529 if (rc < 0)
1541 return rc; 1530 return rc;
1542 } 1531 }
@@ -1568,7 +1557,7 @@ repeat:
1568 table = table->child; 1557 table = table->child;
1569 goto repeat; 1558 goto repeat;
1570 } 1559 }
1571 error = do_sysctl_strategy(root, table, name, nlen, 1560 error = do_sysctl_strategy(root, table,
1572 oldval, oldlenp, 1561 oldval, oldlenp,
1573 newval, newlen); 1562 newval, newlen);
1574 return error; 1563 return error;
@@ -2237,49 +2226,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
2237 NULL,NULL); 2226 NULL,NULL);
2238} 2227}
2239 2228
2240#define OP_SET 0
2241#define OP_AND 1
2242#define OP_OR 2
2243
2244static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
2245 int *valp,
2246 int write, void *data)
2247{
2248 int op = *(int *)data;
2249 if (write) {
2250 int val = *negp ? -*lvalp : *lvalp;
2251 switch(op) {
2252 case OP_SET: *valp = val; break;
2253 case OP_AND: *valp &= val; break;
2254 case OP_OR: *valp |= val; break;
2255 }
2256 } else {
2257 int val = *valp;
2258 if (val < 0) {
2259 *negp = -1;
2260 *lvalp = (unsigned long)-val;
2261 } else {
2262 *negp = 0;
2263 *lvalp = (unsigned long)val;
2264 }
2265 }
2266 return 0;
2267}
2268
2269/* 2229/*
2270 * Taint values can only be increased 2230 * Taint values can only be increased
2231 * This means we can safely use a temporary.
2271 */ 2232 */
2272static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, 2233static int proc_taint(struct ctl_table *table, int write, struct file *filp,
2273 void __user *buffer, size_t *lenp, loff_t *ppos) 2234 void __user *buffer, size_t *lenp, loff_t *ppos)
2274{ 2235{
2275 int op; 2236 struct ctl_table t;
2237 unsigned long tmptaint = get_taint();
2238 int err;
2276 2239
2277 if (write && !capable(CAP_SYS_ADMIN)) 2240 if (write && !capable(CAP_SYS_ADMIN))
2278 return -EPERM; 2241 return -EPERM;
2279 2242
2280 op = OP_OR; 2243 t = *table;
2281 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 2244 t.data = &tmptaint;
2282 do_proc_dointvec_bset_conv,&op); 2245 err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos);
2246 if (err < 0)
2247 return err;
2248
2249 if (write) {
2250 /*
2251 * Poor man's atomic or. Not worth adding a primitive
2252 * to everyone's atomic.h for this
2253 */
2254 int i;
2255 for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2256 if ((tmptaint >> i) & 1)
2257 add_taint(i);
2258 }
2259 }
2260
2261 return err;
2283} 2262}
2284 2263
2285struct do_proc_dointvec_minmax_conv_param { 2264struct do_proc_dointvec_minmax_conv_param {
@@ -2727,7 +2706,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2727 */ 2706 */
2728 2707
2729/* The generic sysctl data routine (used if no strategy routine supplied) */ 2708/* The generic sysctl data routine (used if no strategy routine supplied) */
2730int sysctl_data(struct ctl_table *table, int __user *name, int nlen, 2709int sysctl_data(struct ctl_table *table,
2731 void __user *oldval, size_t __user *oldlenp, 2710 void __user *oldval, size_t __user *oldlenp,
2732 void __user *newval, size_t newlen) 2711 void __user *newval, size_t newlen)
2733{ 2712{
@@ -2761,7 +2740,7 @@ int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
2761} 2740}
2762 2741
2763/* The generic string strategy routine: */ 2742/* The generic string strategy routine: */
2764int sysctl_string(struct ctl_table *table, int __user *name, int nlen, 2743int sysctl_string(struct ctl_table *table,
2765 void __user *oldval, size_t __user *oldlenp, 2744 void __user *oldval, size_t __user *oldlenp,
2766 void __user *newval, size_t newlen) 2745 void __user *newval, size_t newlen)
2767{ 2746{
@@ -2807,7 +2786,7 @@ int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
2807 * are between the minimum and maximum values given in the arrays 2786 * are between the minimum and maximum values given in the arrays
2808 * table->extra1 and table->extra2, respectively. 2787 * table->extra1 and table->extra2, respectively.
2809 */ 2788 */
2810int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, 2789int sysctl_intvec(struct ctl_table *table,
2811 void __user *oldval, size_t __user *oldlenp, 2790 void __user *oldval, size_t __user *oldlenp,
2812 void __user *newval, size_t newlen) 2791 void __user *newval, size_t newlen)
2813{ 2792{
@@ -2843,7 +2822,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
2843} 2822}
2844 2823
2845/* Strategy function to convert jiffies to seconds */ 2824/* Strategy function to convert jiffies to seconds */
2846int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, 2825int sysctl_jiffies(struct ctl_table *table,
2847 void __user *oldval, size_t __user *oldlenp, 2826 void __user *oldval, size_t __user *oldlenp,
2848 void __user *newval, size_t newlen) 2827 void __user *newval, size_t newlen)
2849{ 2828{
@@ -2877,7 +2856,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
2877} 2856}
2878 2857
2879/* Strategy function to convert jiffies to seconds */ 2858/* Strategy function to convert jiffies to seconds */
2880int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, 2859int sysctl_ms_jiffies(struct ctl_table *table,
2881 void __user *oldval, size_t __user *oldlenp, 2860 void __user *oldval, size_t __user *oldlenp,
2882 void __user *newval, size_t newlen) 2861 void __user *newval, size_t newlen)
2883{ 2862{
@@ -2932,35 +2911,35 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
2932 return error; 2911 return error;
2933} 2912}
2934 2913
2935int sysctl_data(struct ctl_table *table, int __user *name, int nlen, 2914int sysctl_data(struct ctl_table *table,
2936 void __user *oldval, size_t __user *oldlenp, 2915 void __user *oldval, size_t __user *oldlenp,
2937 void __user *newval, size_t newlen) 2916 void __user *newval, size_t newlen)
2938{ 2917{
2939 return -ENOSYS; 2918 return -ENOSYS;
2940} 2919}
2941 2920
2942int sysctl_string(struct ctl_table *table, int __user *name, int nlen, 2921int sysctl_string(struct ctl_table *table,
2943 void __user *oldval, size_t __user *oldlenp, 2922 void __user *oldval, size_t __user *oldlenp,
2944 void __user *newval, size_t newlen) 2923 void __user *newval, size_t newlen)
2945{ 2924{
2946 return -ENOSYS; 2925 return -ENOSYS;
2947} 2926}
2948 2927
2949int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, 2928int sysctl_intvec(struct ctl_table *table,
2950 void __user *oldval, size_t __user *oldlenp, 2929 void __user *oldval, size_t __user *oldlenp,
2951 void __user *newval, size_t newlen) 2930 void __user *newval, size_t newlen)
2952{ 2931{
2953 return -ENOSYS; 2932 return -ENOSYS;
2954} 2933}
2955 2934
2956int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, 2935int sysctl_jiffies(struct ctl_table *table,
2957 void __user *oldval, size_t __user *oldlenp, 2936 void __user *oldval, size_t __user *oldlenp,
2958 void __user *newval, size_t newlen) 2937 void __user *newval, size_t newlen)
2959{ 2938{
2960 return -ENOSYS; 2939 return -ENOSYS;
2961} 2940}
2962 2941
2963int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, 2942int sysctl_ms_jiffies(struct ctl_table *table,
2964 void __user *oldval, size_t __user *oldlenp, 2943 void __user *oldval, size_t __user *oldlenp,
2965 void __user *newval, size_t newlen) 2944 void __user *newval, size_t newlen)
2966{ 2945{