aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c115
1 files changed, 48 insertions, 67 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 1bf369bd4423..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
@@ -150,7 +149,7 @@ extern int max_lock_depth;
150#ifdef CONFIG_PROC_SYSCTL 149#ifdef CONFIG_PROC_SYSCTL
151static 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,
152 void __user *buffer, size_t *lenp, loff_t *ppos); 151 void __user *buffer, size_t *lenp, loff_t *ppos);
153static 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,
154 void __user *buffer, size_t *lenp, loff_t *ppos); 153 void __user *buffer, size_t *lenp, loff_t *ppos);
155#endif 154#endif
156 155
@@ -380,10 +379,9 @@ static struct ctl_table kern_table[] = {
380#ifdef CONFIG_PROC_SYSCTL 379#ifdef CONFIG_PROC_SYSCTL
381 { 380 {
382 .procname = "tainted", 381 .procname = "tainted",
383 .data = &tainted, 382 .maxlen = sizeof(long),
384 .maxlen = sizeof(int),
385 .mode = 0644, 383 .mode = 0644,
386 .proc_handler = &proc_dointvec_taint, 384 .proc_handler = &proc_taint,
387 }, 385 },
388#endif 386#endif
389#ifdef CONFIG_LATENCYTOP 387#ifdef CONFIG_LATENCYTOP
@@ -808,16 +806,6 @@ static struct ctl_table kern_table[] = {
808 .proc_handler = &proc_dointvec, 806 .proc_handler = &proc_dointvec,
809 }, 807 },
810#endif 808#endif
811#ifdef CONFIG_PROC_FS
812 {
813 .ctl_name = CTL_UNNUMBERED,
814 .procname = "maps_protect",
815 .data = &maps_protect,
816 .maxlen = sizeof(int),
817 .mode = 0644,
818 .proc_handler = &proc_dointvec,
819 },
820#endif
821 { 809 {
822 .ctl_name = CTL_UNNUMBERED, 810 .ctl_name = CTL_UNNUMBERED,
823 .procname = "poweroff_cmd", 811 .procname = "poweroff_cmd",
@@ -1259,6 +1247,7 @@ static struct ctl_table fs_table[] = {
1259 .extra1 = &minolduid, 1247 .extra1 = &minolduid,
1260 .extra2 = &maxolduid, 1248 .extra2 = &maxolduid,
1261 }, 1249 },
1250#ifdef CONFIG_FILE_LOCKING
1262 { 1251 {
1263 .ctl_name = FS_LEASES, 1252 .ctl_name = FS_LEASES,
1264 .procname = "leases-enable", 1253 .procname = "leases-enable",
@@ -1267,6 +1256,7 @@ static struct ctl_table fs_table[] = {
1267 .mode = 0644, 1256 .mode = 0644,
1268 .proc_handler = &proc_dointvec, 1257 .proc_handler = &proc_dointvec,
1269 }, 1258 },
1259#endif
1270#ifdef CONFIG_DNOTIFY 1260#ifdef CONFIG_DNOTIFY
1271 { 1261 {
1272 .ctl_name = FS_DIR_NOTIFY, 1262 .ctl_name = FS_DIR_NOTIFY,
@@ -1278,6 +1268,7 @@ static struct ctl_table fs_table[] = {
1278 }, 1268 },
1279#endif 1269#endif
1280#ifdef CONFIG_MMU 1270#ifdef CONFIG_MMU
1271#ifdef CONFIG_FILE_LOCKING
1281 { 1272 {
1282 .ctl_name = FS_LEASE_TIME, 1273 .ctl_name = FS_LEASE_TIME,
1283 .procname = "lease-break-time", 1274 .procname = "lease-break-time",
@@ -1289,6 +1280,8 @@ static struct ctl_table fs_table[] = {
1289 .extra1 = &zero, 1280 .extra1 = &zero,
1290 .extra2 = &two, 1281 .extra2 = &two,
1291 }, 1282 },
1283#endif
1284#ifdef CONFIG_AIO
1292 { 1285 {
1293 .procname = "aio-nr", 1286 .procname = "aio-nr",
1294 .data = &aio_nr, 1287 .data = &aio_nr,
@@ -1303,6 +1296,7 @@ static struct ctl_table fs_table[] = {
1303 .mode = 0644, 1296 .mode = 0644,
1304 .proc_handler = &proc_doulongvec_minmax, 1297 .proc_handler = &proc_doulongvec_minmax,
1305 }, 1298 },
1299#endif /* CONFIG_AIO */
1306#ifdef CONFIG_INOTIFY_USER 1300#ifdef CONFIG_INOTIFY_USER
1307 { 1301 {
1308 .ctl_name = FS_INOTIFY, 1302 .ctl_name = FS_INOTIFY,
@@ -1508,7 +1502,6 @@ void register_sysctl_root(struct ctl_table_root *root)
1508/* Perform the actual read/write of a sysctl table entry. */ 1502/* Perform the actual read/write of a sysctl table entry. */
1509static int do_sysctl_strategy(struct ctl_table_root *root, 1503static int do_sysctl_strategy(struct ctl_table_root *root,
1510 struct ctl_table *table, 1504 struct ctl_table *table,
1511 int __user *name, int nlen,
1512 void __user *oldval, size_t __user *oldlenp, 1505 void __user *oldval, size_t __user *oldlenp,
1513 void __user *newval, size_t newlen) 1506 void __user *newval, size_t newlen)
1514{ 1507{
@@ -1522,8 +1515,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
1522 return -EPERM; 1515 return -EPERM;
1523 1516
1524 if (table->strategy) { 1517 if (table->strategy) {
1525 rc = table->strategy(table, name, nlen, oldval, oldlenp, 1518 rc = table->strategy(table, oldval, oldlenp, newval, newlen);
1526 newval, newlen);
1527 if (rc < 0) 1519 if (rc < 0)
1528 return rc; 1520 return rc;
1529 if (rc > 0) 1521 if (rc > 0)
@@ -1533,8 +1525,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
1533 /* If there is no strategy routine, or if the strategy returns 1525 /* If there is no strategy routine, or if the strategy returns
1534 * zero, proceed with automatic r/w */ 1526 * zero, proceed with automatic r/w */
1535 if (table->data && table->maxlen) { 1527 if (table->data && table->maxlen) {
1536 rc = sysctl_data(table, name, nlen, oldval, oldlenp, 1528 rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
1537 newval, newlen);
1538 if (rc < 0) 1529 if (rc < 0)
1539 return rc; 1530 return rc;
1540 } 1531 }
@@ -1566,7 +1557,7 @@ repeat:
1566 table = table->child; 1557 table = table->child;
1567 goto repeat; 1558 goto repeat;
1568 } 1559 }
1569 error = do_sysctl_strategy(root, table, name, nlen, 1560 error = do_sysctl_strategy(root, table,
1570 oldval, oldlenp, 1561 oldval, oldlenp,
1571 newval, newlen); 1562 newval, newlen);
1572 return error; 1563 return error;
@@ -2235,49 +2226,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
2235 NULL,NULL); 2226 NULL,NULL);
2236} 2227}
2237 2228
2238#define OP_SET 0
2239#define OP_AND 1
2240#define OP_OR 2
2241
2242static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
2243 int *valp,
2244 int write, void *data)
2245{
2246 int op = *(int *)data;
2247 if (write) {
2248 int val = *negp ? -*lvalp : *lvalp;
2249 switch(op) {
2250 case OP_SET: *valp = val; break;
2251 case OP_AND: *valp &= val; break;
2252 case OP_OR: *valp |= val; break;
2253 }
2254 } else {
2255 int val = *valp;
2256 if (val < 0) {
2257 *negp = -1;
2258 *lvalp = (unsigned long)-val;
2259 } else {
2260 *negp = 0;
2261 *lvalp = (unsigned long)val;
2262 }
2263 }
2264 return 0;
2265}
2266
2267/* 2229/*
2268 * Taint values can only be increased 2230 * Taint values can only be increased
2231 * This means we can safely use a temporary.
2269 */ 2232 */
2270static 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,
2271 void __user *buffer, size_t *lenp, loff_t *ppos) 2234 void __user *buffer, size_t *lenp, loff_t *ppos)
2272{ 2235{
2273 int op; 2236 struct ctl_table t;
2237 unsigned long tmptaint = get_taint();
2238 int err;
2274 2239
2275 if (write && !capable(CAP_SYS_ADMIN)) 2240 if (write && !capable(CAP_SYS_ADMIN))
2276 return -EPERM; 2241 return -EPERM;
2277 2242
2278 op = OP_OR; 2243 t = *table;
2279 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 2244 t.data = &tmptaint;
2280 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;
2281} 2262}
2282 2263
2283struct do_proc_dointvec_minmax_conv_param { 2264struct do_proc_dointvec_minmax_conv_param {
@@ -2725,7 +2706,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2725 */ 2706 */
2726 2707
2727/* The generic sysctl data routine (used if no strategy routine supplied) */ 2708/* The generic sysctl data routine (used if no strategy routine supplied) */
2728int sysctl_data(struct ctl_table *table, int __user *name, int nlen, 2709int sysctl_data(struct ctl_table *table,
2729 void __user *oldval, size_t __user *oldlenp, 2710 void __user *oldval, size_t __user *oldlenp,
2730 void __user *newval, size_t newlen) 2711 void __user *newval, size_t newlen)
2731{ 2712{
@@ -2759,7 +2740,7 @@ int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
2759} 2740}
2760 2741
2761/* The generic string strategy routine: */ 2742/* The generic string strategy routine: */
2762int sysctl_string(struct ctl_table *table, int __user *name, int nlen, 2743int sysctl_string(struct ctl_table *table,
2763 void __user *oldval, size_t __user *oldlenp, 2744 void __user *oldval, size_t __user *oldlenp,
2764 void __user *newval, size_t newlen) 2745 void __user *newval, size_t newlen)
2765{ 2746{
@@ -2805,7 +2786,7 @@ int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
2805 * are between the minimum and maximum values given in the arrays 2786 * are between the minimum and maximum values given in the arrays
2806 * table->extra1 and table->extra2, respectively. 2787 * table->extra1 and table->extra2, respectively.
2807 */ 2788 */
2808int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, 2789int sysctl_intvec(struct ctl_table *table,
2809 void __user *oldval, size_t __user *oldlenp, 2790 void __user *oldval, size_t __user *oldlenp,
2810 void __user *newval, size_t newlen) 2791 void __user *newval, size_t newlen)
2811{ 2792{
@@ -2841,7 +2822,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
2841} 2822}
2842 2823
2843/* Strategy function to convert jiffies to seconds */ 2824/* Strategy function to convert jiffies to seconds */
2844int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, 2825int sysctl_jiffies(struct ctl_table *table,
2845 void __user *oldval, size_t __user *oldlenp, 2826 void __user *oldval, size_t __user *oldlenp,
2846 void __user *newval, size_t newlen) 2827 void __user *newval, size_t newlen)
2847{ 2828{
@@ -2875,7 +2856,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
2875} 2856}
2876 2857
2877/* Strategy function to convert jiffies to seconds */ 2858/* Strategy function to convert jiffies to seconds */
2878int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, 2859int sysctl_ms_jiffies(struct ctl_table *table,
2879 void __user *oldval, size_t __user *oldlenp, 2860 void __user *oldval, size_t __user *oldlenp,
2880 void __user *newval, size_t newlen) 2861 void __user *newval, size_t newlen)
2881{ 2862{
@@ -2930,35 +2911,35 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
2930 return error; 2911 return error;
2931} 2912}
2932 2913
2933int sysctl_data(struct ctl_table *table, int __user *name, int nlen, 2914int sysctl_data(struct ctl_table *table,
2934 void __user *oldval, size_t __user *oldlenp, 2915 void __user *oldval, size_t __user *oldlenp,
2935 void __user *newval, size_t newlen) 2916 void __user *newval, size_t newlen)
2936{ 2917{
2937 return -ENOSYS; 2918 return -ENOSYS;
2938} 2919}
2939 2920
2940int sysctl_string(struct ctl_table *table, int __user *name, int nlen, 2921int sysctl_string(struct ctl_table *table,
2941 void __user *oldval, size_t __user *oldlenp, 2922 void __user *oldval, size_t __user *oldlenp,
2942 void __user *newval, size_t newlen) 2923 void __user *newval, size_t newlen)
2943{ 2924{
2944 return -ENOSYS; 2925 return -ENOSYS;
2945} 2926}
2946 2927
2947int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, 2928int sysctl_intvec(struct ctl_table *table,
2948 void __user *oldval, size_t __user *oldlenp, 2929 void __user *oldval, size_t __user *oldlenp,
2949 void __user *newval, size_t newlen) 2930 void __user *newval, size_t newlen)
2950{ 2931{
2951 return -ENOSYS; 2932 return -ENOSYS;
2952} 2933}
2953 2934
2954int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, 2935int sysctl_jiffies(struct ctl_table *table,
2955 void __user *oldval, size_t __user *oldlenp, 2936 void __user *oldval, size_t __user *oldlenp,
2956 void __user *newval, size_t newlen) 2937 void __user *newval, size_t newlen)
2957{ 2938{
2958 return -ENOSYS; 2939 return -ENOSYS;
2959} 2940}
2960 2941
2961int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, 2942int sysctl_ms_jiffies(struct ctl_table *table,
2962 void __user *oldval, size_t __user *oldlenp, 2943 void __user *oldval, size_t __user *oldlenp,
2963 void __user *newval, size_t newlen) 2944 void __user *newval, size_t newlen)
2964{ 2945{