diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-05 19:05:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-05 19:05:24 -0400 |
commit | 7114f51fcb979f167ab5f625ac74059dcb1afc28 (patch) | |
tree | cb15e7498eccb41a38bd2ff20e873ffb0bfb7c1d | |
parent | ea3b25e1320df4e575c323b6ab22a5fc79976fbe (diff) | |
parent | e4448ed87ccdbacb74871736f63220642242b32f (diff) |
Merge branch 'work.memdup_user' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull memdup_user() conversions from Al Viro:
"A fairly self-contained series - hunting down open-coded memdup_user()
and memdup_user_nul() instances"
* 'work.memdup_user' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
bpf: don't open-code memdup_user()
kimage_file_prepare_segments(): don't open-code memdup_user()
ethtool: don't open-code memdup_user()
do_ip_setsockopt(): don't open-code memdup_user()
do_ipv6_setsockopt(): don't open-code memdup_user()
irda: don't open-code memdup_user()
xfrm_user_policy(): don't open-code memdup_user()
ima_write_policy(): don't open-code memdup_user_nul()
sel_write_validatetrans(): don't open-code memdup_user_nul()
-rw-r--r-- | kernel/bpf/syscall.c | 45 | ||||
-rw-r--r-- | kernel/kexec_file.c | 14 | ||||
-rw-r--r-- | net/core/ethtool.c | 20 | ||||
-rw-r--r-- | net/ipv4/ip_sockglue.c | 20 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 11 | ||||
-rw-r--r-- | net/irda/af_irda.c | 48 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 12 |
7 files changed, 52 insertions, 118 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 18980472f5b0..045646da97cc 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -410,14 +410,11 @@ static int map_lookup_elem(union bpf_attr *attr) | |||
410 | if (IS_ERR(map)) | 410 | if (IS_ERR(map)) |
411 | return PTR_ERR(map); | 411 | return PTR_ERR(map); |
412 | 412 | ||
413 | err = -ENOMEM; | 413 | key = memdup_user(ukey, map->key_size); |
414 | key = kmalloc(map->key_size, GFP_USER); | 414 | if (IS_ERR(key)) { |
415 | if (!key) | 415 | err = PTR_ERR(key); |
416 | goto err_put; | 416 | goto err_put; |
417 | 417 | } | |
418 | err = -EFAULT; | ||
419 | if (copy_from_user(key, ukey, map->key_size) != 0) | ||
420 | goto free_key; | ||
421 | 418 | ||
422 | if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || | 419 | if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || |
423 | map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || | 420 | map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || |
@@ -493,14 +490,11 @@ static int map_update_elem(union bpf_attr *attr) | |||
493 | if (IS_ERR(map)) | 490 | if (IS_ERR(map)) |
494 | return PTR_ERR(map); | 491 | return PTR_ERR(map); |
495 | 492 | ||
496 | err = -ENOMEM; | 493 | key = memdup_user(ukey, map->key_size); |
497 | key = kmalloc(map->key_size, GFP_USER); | 494 | if (IS_ERR(key)) { |
498 | if (!key) | 495 | err = PTR_ERR(key); |
499 | goto err_put; | 496 | goto err_put; |
500 | 497 | } | |
501 | err = -EFAULT; | ||
502 | if (copy_from_user(key, ukey, map->key_size) != 0) | ||
503 | goto free_key; | ||
504 | 498 | ||
505 | if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || | 499 | if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || |
506 | map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || | 500 | map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || |
@@ -579,14 +573,11 @@ static int map_delete_elem(union bpf_attr *attr) | |||
579 | if (IS_ERR(map)) | 573 | if (IS_ERR(map)) |
580 | return PTR_ERR(map); | 574 | return PTR_ERR(map); |
581 | 575 | ||
582 | err = -ENOMEM; | 576 | key = memdup_user(ukey, map->key_size); |
583 | key = kmalloc(map->key_size, GFP_USER); | 577 | if (IS_ERR(key)) { |
584 | if (!key) | 578 | err = PTR_ERR(key); |
585 | goto err_put; | 579 | goto err_put; |
586 | 580 | } | |
587 | err = -EFAULT; | ||
588 | if (copy_from_user(key, ukey, map->key_size) != 0) | ||
589 | goto free_key; | ||
590 | 581 | ||
591 | preempt_disable(); | 582 | preempt_disable(); |
592 | __this_cpu_inc(bpf_prog_active); | 583 | __this_cpu_inc(bpf_prog_active); |
@@ -598,7 +589,6 @@ static int map_delete_elem(union bpf_attr *attr) | |||
598 | 589 | ||
599 | if (!err) | 590 | if (!err) |
600 | trace_bpf_map_delete_elem(map, ufd, key); | 591 | trace_bpf_map_delete_elem(map, ufd, key); |
601 | free_key: | ||
602 | kfree(key); | 592 | kfree(key); |
603 | err_put: | 593 | err_put: |
604 | fdput(f); | 594 | fdput(f); |
@@ -627,14 +617,11 @@ static int map_get_next_key(union bpf_attr *attr) | |||
627 | return PTR_ERR(map); | 617 | return PTR_ERR(map); |
628 | 618 | ||
629 | if (ukey) { | 619 | if (ukey) { |
630 | err = -ENOMEM; | 620 | key = memdup_user(ukey, map->key_size); |
631 | key = kmalloc(map->key_size, GFP_USER); | 621 | if (IS_ERR(key)) { |
632 | if (!key) | 622 | err = PTR_ERR(key); |
633 | goto err_put; | 623 | goto err_put; |
634 | 624 | } | |
635 | err = -EFAULT; | ||
636 | if (copy_from_user(key, ukey, map->key_size) != 0) | ||
637 | goto free_key; | ||
638 | } else { | 625 | } else { |
639 | key = NULL; | 626 | key = NULL; |
640 | } | 627 | } |
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b118735fea9d..766e7e4d3ad9 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -162,16 +162,10 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, | |||
162 | } | 162 | } |
163 | 163 | ||
164 | if (cmdline_len) { | 164 | if (cmdline_len) { |
165 | image->cmdline_buf = kzalloc(cmdline_len, GFP_KERNEL); | 165 | image->cmdline_buf = memdup_user(cmdline_ptr, cmdline_len); |
166 | if (!image->cmdline_buf) { | 166 | if (IS_ERR(image->cmdline_buf)) { |
167 | ret = -ENOMEM; | 167 | ret = PTR_ERR(image->cmdline_buf); |
168 | goto out; | 168 | image->cmdline_buf = NULL; |
169 | } | ||
170 | |||
171 | ret = copy_from_user(image->cmdline_buf, cmdline_ptr, | ||
172 | cmdline_len); | ||
173 | if (ret) { | ||
174 | ret = -EFAULT; | ||
175 | goto out; | 169 | goto out; |
176 | } | 170 | } |
177 | 171 | ||
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 03111a2d6653..674b6c9cec18 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -2322,16 +2322,12 @@ static int ethtool_set_tunable(struct net_device *dev, void __user *useraddr) | |||
2322 | ret = ethtool_tunable_valid(&tuna); | 2322 | ret = ethtool_tunable_valid(&tuna); |
2323 | if (ret) | 2323 | if (ret) |
2324 | return ret; | 2324 | return ret; |
2325 | data = kmalloc(tuna.len, GFP_USER); | ||
2326 | if (!data) | ||
2327 | return -ENOMEM; | ||
2328 | useraddr += sizeof(tuna); | 2325 | useraddr += sizeof(tuna); |
2329 | ret = -EFAULT; | 2326 | data = memdup_user(useraddr, tuna.len); |
2330 | if (copy_from_user(data, useraddr, tuna.len)) | 2327 | if (IS_ERR(data)) |
2331 | goto out; | 2328 | return PTR_ERR(data); |
2332 | ret = ops->set_tunable(dev, &tuna, data); | 2329 | ret = ops->set_tunable(dev, &tuna, data); |
2333 | 2330 | ||
2334 | out: | ||
2335 | kfree(data); | 2331 | kfree(data); |
2336 | return ret; | 2332 | return ret; |
2337 | } | 2333 | } |
@@ -2507,18 +2503,14 @@ static int set_phy_tunable(struct net_device *dev, void __user *useraddr) | |||
2507 | ret = ethtool_phy_tunable_valid(&tuna); | 2503 | ret = ethtool_phy_tunable_valid(&tuna); |
2508 | if (ret) | 2504 | if (ret) |
2509 | return ret; | 2505 | return ret; |
2510 | data = kmalloc(tuna.len, GFP_USER); | ||
2511 | if (!data) | ||
2512 | return -ENOMEM; | ||
2513 | useraddr += sizeof(tuna); | 2506 | useraddr += sizeof(tuna); |
2514 | ret = -EFAULT; | 2507 | data = memdup_user(useraddr, tuna.len); |
2515 | if (copy_from_user(data, useraddr, tuna.len)) | 2508 | if (IS_ERR(data)) |
2516 | goto out; | 2509 | return PTR_ERR(data); |
2517 | mutex_lock(&phydev->lock); | 2510 | mutex_lock(&phydev->lock); |
2518 | ret = phydev->drv->set_tunable(phydev, &tuna, data); | 2511 | ret = phydev->drv->set_tunable(phydev, &tuna, data); |
2519 | mutex_unlock(&phydev->lock); | 2512 | mutex_unlock(&phydev->lock); |
2520 | 2513 | ||
2521 | out: | ||
2522 | kfree(data); | 2514 | kfree(data); |
2523 | return ret; | 2515 | return ret; |
2524 | } | 2516 | } |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ec4fe3d4b5c9..ecc4b4a2413e 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -934,14 +934,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
934 | err = -ENOBUFS; | 934 | err = -ENOBUFS; |
935 | break; | 935 | break; |
936 | } | 936 | } |
937 | msf = kmalloc(optlen, GFP_KERNEL); | 937 | msf = memdup_user(optval, optlen); |
938 | if (!msf) { | 938 | if (IS_ERR(msf)) { |
939 | err = -ENOBUFS; | 939 | err = PTR_ERR(msf); |
940 | break; | ||
941 | } | ||
942 | err = -EFAULT; | ||
943 | if (copy_from_user(msf, optval, optlen)) { | ||
944 | kfree(msf); | ||
945 | break; | 940 | break; |
946 | } | 941 | } |
947 | /* numsrc >= (1G-4) overflow in 32 bits */ | 942 | /* numsrc >= (1G-4) overflow in 32 bits */ |
@@ -1090,14 +1085,11 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
1090 | err = -ENOBUFS; | 1085 | err = -ENOBUFS; |
1091 | break; | 1086 | break; |
1092 | } | 1087 | } |
1093 | gsf = kmalloc(optlen, GFP_KERNEL); | 1088 | gsf = memdup_user(optval, optlen); |
1094 | if (!gsf) { | 1089 | if (IS_ERR(gsf)) { |
1095 | err = -ENOBUFS; | 1090 | err = PTR_ERR(gsf); |
1096 | break; | 1091 | break; |
1097 | } | 1092 | } |
1098 | err = -EFAULT; | ||
1099 | if (copy_from_user(gsf, optval, optlen)) | ||
1100 | goto mc_msf_out; | ||
1101 | 1093 | ||
1102 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ | 1094 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ |
1103 | if (gsf->gf_numsrc >= 0x1ffffff || | 1095 | if (gsf->gf_numsrc >= 0x1ffffff || |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 85404e7c3114..02d795fe3d7f 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -735,14 +735,9 @@ done: | |||
735 | retv = -ENOBUFS; | 735 | retv = -ENOBUFS; |
736 | break; | 736 | break; |
737 | } | 737 | } |
738 | gsf = kmalloc(optlen, GFP_KERNEL); | 738 | gsf = memdup_user(optval, optlen); |
739 | if (!gsf) { | 739 | if (IS_ERR(gsf)) { |
740 | retv = -ENOBUFS; | 740 | retv = PTR_ERR(gsf); |
741 | break; | ||
742 | } | ||
743 | retv = -EFAULT; | ||
744 | if (copy_from_user(gsf, optval, optlen)) { | ||
745 | kfree(gsf); | ||
746 | break; | 741 | break; |
747 | } | 742 | } |
748 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ | 743 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 8d77ad5cadaf..2e6990f8b80b 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -1901,16 +1901,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, | |||
1901 | goto out; | 1901 | goto out; |
1902 | } | 1902 | } |
1903 | 1903 | ||
1904 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | ||
1905 | if (ias_opt == NULL) { | ||
1906 | err = -ENOMEM; | ||
1907 | goto out; | ||
1908 | } | ||
1909 | |||
1910 | /* Copy query to the driver. */ | 1904 | /* Copy query to the driver. */ |
1911 | if (copy_from_user(ias_opt, optval, optlen)) { | 1905 | ias_opt = memdup_user(optval, optlen); |
1912 | kfree(ias_opt); | 1906 | if (IS_ERR(ias_opt)) { |
1913 | err = -EFAULT; | 1907 | err = PTR_ERR(ias_opt); |
1914 | goto out; | 1908 | goto out; |
1915 | } | 1909 | } |
1916 | 1910 | ||
@@ -2032,16 +2026,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, | |||
2032 | goto out; | 2026 | goto out; |
2033 | } | 2027 | } |
2034 | 2028 | ||
2035 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | ||
2036 | if (ias_opt == NULL) { | ||
2037 | err = -ENOMEM; | ||
2038 | goto out; | ||
2039 | } | ||
2040 | |||
2041 | /* Copy query to the driver. */ | 2029 | /* Copy query to the driver. */ |
2042 | if (copy_from_user(ias_opt, optval, optlen)) { | 2030 | ias_opt = memdup_user(optval, optlen); |
2043 | kfree(ias_opt); | 2031 | if (IS_ERR(ias_opt)) { |
2044 | err = -EFAULT; | 2032 | err = PTR_ERR(ias_opt); |
2045 | goto out; | 2033 | goto out; |
2046 | } | 2034 | } |
2047 | 2035 | ||
@@ -2317,16 +2305,10 @@ bed: | |||
2317 | goto out; | 2305 | goto out; |
2318 | } | 2306 | } |
2319 | 2307 | ||
2320 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | ||
2321 | if (ias_opt == NULL) { | ||
2322 | err = -ENOMEM; | ||
2323 | goto out; | ||
2324 | } | ||
2325 | |||
2326 | /* Copy query to the driver. */ | 2308 | /* Copy query to the driver. */ |
2327 | if (copy_from_user(ias_opt, optval, len)) { | 2309 | ias_opt = memdup_user(optval, len); |
2328 | kfree(ias_opt); | 2310 | if (IS_ERR(ias_opt)) { |
2329 | err = -EFAULT; | 2311 | err = PTR_ERR(ias_opt); |
2330 | goto out; | 2312 | goto out; |
2331 | } | 2313 | } |
2332 | 2314 | ||
@@ -2381,16 +2363,10 @@ bed: | |||
2381 | goto out; | 2363 | goto out; |
2382 | } | 2364 | } |
2383 | 2365 | ||
2384 | ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); | ||
2385 | if (ias_opt == NULL) { | ||
2386 | err = -ENOMEM; | ||
2387 | goto out; | ||
2388 | } | ||
2389 | |||
2390 | /* Copy query to the driver. */ | 2366 | /* Copy query to the driver. */ |
2391 | if (copy_from_user(ias_opt, optval, len)) { | 2367 | ias_opt = memdup_user(optval, len); |
2392 | kfree(ias_opt); | 2368 | if (IS_ERR(ias_opt)) { |
2393 | err = -EFAULT; | 2369 | err = PTR_ERR(ias_opt); |
2394 | goto out; | 2370 | goto out; |
2395 | } | 2371 | } |
2396 | 2372 | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 9010a3632d6f..00eed842c491 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -649,14 +649,12 @@ static ssize_t sel_write_validatetrans(struct file *file, | |||
649 | if (*ppos != 0) | 649 | if (*ppos != 0) |
650 | goto out; | 650 | goto out; |
651 | 651 | ||
652 | rc = -ENOMEM; | 652 | req = memdup_user_nul(buf, count); |
653 | req = kzalloc(count + 1, GFP_KERNEL); | 653 | if (IS_ERR(req)) { |
654 | if (!req) | 654 | rc = PTR_ERR(req); |
655 | goto out; | 655 | req = NULL; |
656 | |||
657 | rc = -EFAULT; | ||
658 | if (copy_from_user(req, buf, count)) | ||
659 | goto out; | 656 | goto out; |
657 | } | ||
660 | 658 | ||
661 | rc = -ENOMEM; | 659 | rc = -ENOMEM; |
662 | oldcon = kzalloc(count + 1, GFP_KERNEL); | 660 | oldcon = kzalloc(count + 1, GFP_KERNEL); |