diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 79 |
1 files changed, 28 insertions, 51 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index dc6858d6639e..5faf89ac9ec0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -2047,9 +2047,8 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | |||
2047 | void *data) | 2047 | void *data) |
2048 | { | 2048 | { |
2049 | int *i, vleft, first = 1, err = 0; | 2049 | int *i, vleft, first = 1, err = 0; |
2050 | unsigned long page = 0; | ||
2051 | size_t left; | 2050 | size_t left; |
2052 | char *kbuf; | 2051 | char *kbuf = NULL, *p; |
2053 | 2052 | ||
2054 | if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) { | 2053 | if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) { |
2055 | *lenp = 0; | 2054 | *lenp = 0; |
@@ -2078,15 +2077,9 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | |||
2078 | 2077 | ||
2079 | if (left > PAGE_SIZE - 1) | 2078 | if (left > PAGE_SIZE - 1) |
2080 | left = PAGE_SIZE - 1; | 2079 | left = PAGE_SIZE - 1; |
2081 | page = __get_free_page(GFP_TEMPORARY); | 2080 | p = kbuf = memdup_user_nul(buffer, left); |
2082 | kbuf = (char *) page; | 2081 | if (IS_ERR(kbuf)) |
2083 | if (!kbuf) | 2082 | return PTR_ERR(kbuf); |
2084 | return -ENOMEM; | ||
2085 | if (copy_from_user(kbuf, buffer, left)) { | ||
2086 | err = -EFAULT; | ||
2087 | goto free; | ||
2088 | } | ||
2089 | kbuf[left] = 0; | ||
2090 | } | 2083 | } |
2091 | 2084 | ||
2092 | for (; left && vleft--; i++, first=0) { | 2085 | for (; left && vleft--; i++, first=0) { |
@@ -2094,11 +2087,11 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | |||
2094 | bool neg; | 2087 | bool neg; |
2095 | 2088 | ||
2096 | if (write) { | 2089 | if (write) { |
2097 | left -= proc_skip_spaces(&kbuf); | 2090 | left -= proc_skip_spaces(&p); |
2098 | 2091 | ||
2099 | if (!left) | 2092 | if (!left) |
2100 | break; | 2093 | break; |
2101 | err = proc_get_long(&kbuf, &left, &lval, &neg, | 2094 | err = proc_get_long(&p, &left, &lval, &neg, |
2102 | proc_wspace_sep, | 2095 | proc_wspace_sep, |
2103 | sizeof(proc_wspace_sep), NULL); | 2096 | sizeof(proc_wspace_sep), NULL); |
2104 | if (err) | 2097 | if (err) |
@@ -2125,10 +2118,9 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, | |||
2125 | if (!write && !first && left && !err) | 2118 | if (!write && !first && left && !err) |
2126 | err = proc_put_char(&buffer, &left, '\n'); | 2119 | err = proc_put_char(&buffer, &left, '\n'); |
2127 | if (write && !err && left) | 2120 | if (write && !err && left) |
2128 | left -= proc_skip_spaces(&kbuf); | 2121 | left -= proc_skip_spaces(&p); |
2129 | free: | ||
2130 | if (write) { | 2122 | if (write) { |
2131 | free_page(page); | 2123 | kfree(kbuf); |
2132 | if (first) | 2124 | if (first) |
2133 | return err ? : -EINVAL; | 2125 | return err ? : -EINVAL; |
2134 | } | 2126 | } |
@@ -2310,9 +2302,8 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
2310 | { | 2302 | { |
2311 | unsigned long *i, *min, *max; | 2303 | unsigned long *i, *min, *max; |
2312 | int vleft, first = 1, err = 0; | 2304 | int vleft, first = 1, err = 0; |
2313 | unsigned long page = 0; | ||
2314 | size_t left; | 2305 | size_t left; |
2315 | char *kbuf; | 2306 | char *kbuf = NULL, *p; |
2316 | 2307 | ||
2317 | if (!data || !table->maxlen || !*lenp || (*ppos && !write)) { | 2308 | if (!data || !table->maxlen || !*lenp || (*ppos && !write)) { |
2318 | *lenp = 0; | 2309 | *lenp = 0; |
@@ -2340,15 +2331,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
2340 | 2331 | ||
2341 | if (left > PAGE_SIZE - 1) | 2332 | if (left > PAGE_SIZE - 1) |
2342 | left = PAGE_SIZE - 1; | 2333 | left = PAGE_SIZE - 1; |
2343 | page = __get_free_page(GFP_TEMPORARY); | 2334 | p = kbuf = memdup_user_nul(buffer, left); |
2344 | kbuf = (char *) page; | 2335 | if (IS_ERR(kbuf)) |
2345 | if (!kbuf) | 2336 | return PTR_ERR(kbuf); |
2346 | return -ENOMEM; | ||
2347 | if (copy_from_user(kbuf, buffer, left)) { | ||
2348 | err = -EFAULT; | ||
2349 | goto free; | ||
2350 | } | ||
2351 | kbuf[left] = 0; | ||
2352 | } | 2337 | } |
2353 | 2338 | ||
2354 | for (; left && vleft--; i++, first = 0) { | 2339 | for (; left && vleft--; i++, first = 0) { |
@@ -2357,9 +2342,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
2357 | if (write) { | 2342 | if (write) { |
2358 | bool neg; | 2343 | bool neg; |
2359 | 2344 | ||
2360 | left -= proc_skip_spaces(&kbuf); | 2345 | left -= proc_skip_spaces(&p); |
2361 | 2346 | ||
2362 | err = proc_get_long(&kbuf, &left, &val, &neg, | 2347 | err = proc_get_long(&p, &left, &val, &neg, |
2363 | proc_wspace_sep, | 2348 | proc_wspace_sep, |
2364 | sizeof(proc_wspace_sep), NULL); | 2349 | sizeof(proc_wspace_sep), NULL); |
2365 | if (err) | 2350 | if (err) |
@@ -2385,10 +2370,9 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
2385 | if (!write && !first && left && !err) | 2370 | if (!write && !first && left && !err) |
2386 | err = proc_put_char(&buffer, &left, '\n'); | 2371 | err = proc_put_char(&buffer, &left, '\n'); |
2387 | if (write && !err) | 2372 | if (write && !err) |
2388 | left -= proc_skip_spaces(&kbuf); | 2373 | left -= proc_skip_spaces(&p); |
2389 | free: | ||
2390 | if (write) { | 2374 | if (write) { |
2391 | free_page(page); | 2375 | kfree(kbuf); |
2392 | if (first) | 2376 | if (first) |
2393 | return err ? : -EINVAL; | 2377 | return err ? : -EINVAL; |
2394 | } | 2378 | } |
@@ -2650,34 +2634,27 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, | |||
2650 | } | 2634 | } |
2651 | 2635 | ||
2652 | if (write) { | 2636 | if (write) { |
2653 | unsigned long page = 0; | 2637 | char *kbuf, *p; |
2654 | char *kbuf; | ||
2655 | 2638 | ||
2656 | if (left > PAGE_SIZE - 1) | 2639 | if (left > PAGE_SIZE - 1) |
2657 | left = PAGE_SIZE - 1; | 2640 | left = PAGE_SIZE - 1; |
2658 | 2641 | ||
2659 | page = __get_free_page(GFP_TEMPORARY); | 2642 | p = kbuf = memdup_user_nul(buffer, left); |
2660 | kbuf = (char *) page; | 2643 | if (IS_ERR(kbuf)) |
2661 | if (!kbuf) | 2644 | return PTR_ERR(kbuf); |
2662 | return -ENOMEM; | ||
2663 | if (copy_from_user(kbuf, buffer, left)) { | ||
2664 | free_page(page); | ||
2665 | return -EFAULT; | ||
2666 | } | ||
2667 | kbuf[left] = 0; | ||
2668 | 2645 | ||
2669 | tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long), | 2646 | tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long), |
2670 | GFP_KERNEL); | 2647 | GFP_KERNEL); |
2671 | if (!tmp_bitmap) { | 2648 | if (!tmp_bitmap) { |
2672 | free_page(page); | 2649 | kfree(kbuf); |
2673 | return -ENOMEM; | 2650 | return -ENOMEM; |
2674 | } | 2651 | } |
2675 | proc_skip_char(&kbuf, &left, '\n'); | 2652 | proc_skip_char(&p, &left, '\n'); |
2676 | while (!err && left) { | 2653 | while (!err && left) { |
2677 | unsigned long val_a, val_b; | 2654 | unsigned long val_a, val_b; |
2678 | bool neg; | 2655 | bool neg; |
2679 | 2656 | ||
2680 | err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a, | 2657 | err = proc_get_long(&p, &left, &val_a, &neg, tr_a, |
2681 | sizeof(tr_a), &c); | 2658 | sizeof(tr_a), &c); |
2682 | if (err) | 2659 | if (err) |
2683 | break; | 2660 | break; |
@@ -2688,12 +2665,12 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, | |||
2688 | 2665 | ||
2689 | val_b = val_a; | 2666 | val_b = val_a; |
2690 | if (left) { | 2667 | if (left) { |
2691 | kbuf++; | 2668 | p++; |
2692 | left--; | 2669 | left--; |
2693 | } | 2670 | } |
2694 | 2671 | ||
2695 | if (c == '-') { | 2672 | if (c == '-') { |
2696 | err = proc_get_long(&kbuf, &left, &val_b, | 2673 | err = proc_get_long(&p, &left, &val_b, |
2697 | &neg, tr_b, sizeof(tr_b), | 2674 | &neg, tr_b, sizeof(tr_b), |
2698 | &c); | 2675 | &c); |
2699 | if (err) | 2676 | if (err) |
@@ -2704,16 +2681,16 @@ int proc_do_large_bitmap(struct ctl_table *table, int write, | |||
2704 | break; | 2681 | break; |
2705 | } | 2682 | } |
2706 | if (left) { | 2683 | if (left) { |
2707 | kbuf++; | 2684 | p++; |
2708 | left--; | 2685 | left--; |
2709 | } | 2686 | } |
2710 | } | 2687 | } |
2711 | 2688 | ||
2712 | bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1); | 2689 | bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1); |
2713 | first = 0; | 2690 | first = 0; |
2714 | proc_skip_char(&kbuf, &left, '\n'); | 2691 | proc_skip_char(&p, &left, '\n'); |
2715 | } | 2692 | } |
2716 | free_page(page); | 2693 | kfree(kbuf); |
2717 | } else { | 2694 | } else { |
2718 | unsigned long bit_a, bit_b = 0; | 2695 | unsigned long bit_a, bit_b = 0; |
2719 | 2696 | ||