diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 115 |
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; | |||
80 | extern int sysctl_drop_caches; | 80 | extern int sysctl_drop_caches; |
81 | extern int percpu_pagelist_fraction; | 81 | extern int percpu_pagelist_fraction; |
82 | extern int compat_log; | 82 | extern int compat_log; |
83 | extern int maps_protect; | ||
84 | extern int latencytop_enabled; | 83 | extern int latencytop_enabled; |
85 | extern int sysctl_nr_open_min, sysctl_nr_open_max; | 84 | extern 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; | |||
97 | static int neg_one = -1; | 96 | static int neg_one = -1; |
98 | #endif | 97 | #endif |
99 | 98 | ||
100 | #ifdef CONFIG_MMU | 99 | #if defined(CONFIG_MMU) && defined(CONFIG_FILE_LOCKING) |
101 | static int two = 2; | 100 | static 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 |
151 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 150 | static 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); |
153 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 152 | static 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. */ |
1509 | static int do_sysctl_strategy(struct ctl_table_root *root, | 1503 | static 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 | |||
2242 | static 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 | */ |
2270 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 2233 | static 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 | ||
2283 | struct do_proc_dointvec_minmax_conv_param { | 2264 | struct 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) */ |
2728 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2709 | int 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: */ |
2762 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2743 | int 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 | */ |
2808 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2789 | int 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 */ |
2844 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2825 | int 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 */ |
2878 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2859 | int 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 | ||
2933 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | 2914 | int 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 | ||
2940 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, | 2921 | int 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 | ||
2947 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, | 2928 | int 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 | ||
2954 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2935 | int 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 | ||
2961 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, | 2942 | int 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 | { |