aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c79
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);
2129free:
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);
2389free:
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