aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 19:05:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-05 19:05:24 -0400
commit7114f51fcb979f167ab5f625ac74059dcb1afc28 (patch)
treecb15e7498eccb41a38bd2ff20e873ffb0bfb7c1d
parentea3b25e1320df4e575c323b6ab22a5fc79976fbe (diff)
parente4448ed87ccdbacb74871736f63220642242b32f (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.c45
-rw-r--r--kernel/kexec_file.c14
-rw-r--r--net/core/ethtool.c20
-rw-r--r--net/ipv4/ip_sockglue.c20
-rw-r--r--net/ipv6/ipv6_sockglue.c11
-rw-r--r--net/irda/af_irda.c48
-rw-r--r--security/selinux/selinuxfs.c12
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);
601free_key:
602 kfree(key); 592 kfree(key);
603err_put: 593err_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
2334out:
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
2521out:
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);