@@ -970,13 +970,6 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
970
970
* This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
971
971
* from userspace.
972
972
*
973
- * We don't use copy_from_user() for optimization: we first do the
974
- * sanity checks (buffer size -fast- and access check-healthy
975
- * pointer); if all of those succeed, then we can alloc the memory
976
- * (expensive operation) needed to copy the data to kernel. Then we do
977
- * the copying without checking the user space area
978
- * (__copy_from_user()).
979
- *
980
973
* On exit there is no need to do sockfd_put(), sys_setsockopt() does
981
974
* it.
982
975
*
@@ -1006,25 +999,15 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1006
999
if (unlikely (addrs_size <= 0 ))
1007
1000
return - EINVAL ;
1008
1001
1009
- /* Check the user passed a healthy pointer. */
1010
- if (unlikely (!access_ok (VERIFY_READ , addrs , addrs_size )))
1011
- return - EFAULT ;
1012
-
1013
- /* Alloc space for the address array in kernel memory. */
1014
- kaddrs = kmalloc (addrs_size , GFP_USER | __GFP_NOWARN );
1015
- if (unlikely (!kaddrs ))
1016
- return - ENOMEM ;
1017
-
1018
- if (__copy_from_user (kaddrs , addrs , addrs_size )) {
1019
- kfree (kaddrs );
1020
- return - EFAULT ;
1021
- }
1002
+ kaddrs = vmemdup_user (addrs , addrs_size );
1003
+ if (unlikely (IS_ERR (kaddrs )))
1004
+ return PTR_ERR (kaddrs );
1022
1005
1023
1006
/* Walk through the addrs buffer and count the number of addresses. */
1024
1007
addr_buf = kaddrs ;
1025
1008
while (walk_size < addrs_size ) {
1026
1009
if (walk_size + sizeof (sa_family_t ) > addrs_size ) {
1027
- kfree (kaddrs );
1010
+ kvfree (kaddrs );
1028
1011
return - EINVAL ;
1029
1012
}
1030
1013
@@ -1035,7 +1018,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1035
1018
* causes the address buffer to overflow return EINVAL.
1036
1019
*/
1037
1020
if (!af || (walk_size + af -> sockaddr_len ) > addrs_size ) {
1038
- kfree (kaddrs );
1021
+ kvfree (kaddrs );
1039
1022
return - EINVAL ;
1040
1023
}
1041
1024
addrcnt ++ ;
@@ -1065,7 +1048,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1065
1048
}
1066
1049
1067
1050
out :
1068
- kfree (kaddrs );
1051
+ kvfree (kaddrs );
1069
1052
1070
1053
return err ;
1071
1054
}
@@ -1323,13 +1306,6 @@ static int __sctp_connect(struct sock *sk,
1323
1306
* land and invoking either sctp_connectx(). This is used for tunneling
1324
1307
* the sctp_connectx() request through sctp_setsockopt() from userspace.
1325
1308
*
1326
- * We don't use copy_from_user() for optimization: we first do the
1327
- * sanity checks (buffer size -fast- and access check-healthy
1328
- * pointer); if all of those succeed, then we can alloc the memory
1329
- * (expensive operation) needed to copy the data to kernel. Then we do
1330
- * the copying without checking the user space area
1331
- * (__copy_from_user()).
1332
- *
1333
1309
* On exit there is no need to do sockfd_put(), sys_setsockopt() does
1334
1310
* it.
1335
1311
*
@@ -1345,7 +1321,6 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
1345
1321
sctp_assoc_t * assoc_id )
1346
1322
{
1347
1323
struct sockaddr * kaddrs ;
1348
- gfp_t gfp = GFP_KERNEL ;
1349
1324
int err = 0 ;
1350
1325
1351
1326
pr_debug ("%s: sk:%p addrs:%p addrs_size:%d\n" ,
@@ -1354,24 +1329,12 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
1354
1329
if (unlikely (addrs_size <= 0 ))
1355
1330
return - EINVAL ;
1356
1331
1357
- /* Check the user passed a healthy pointer. */
1358
- if (unlikely (!access_ok (VERIFY_READ , addrs , addrs_size )))
1359
- return - EFAULT ;
1360
-
1361
- /* Alloc space for the address array in kernel memory. */
1362
- if (sk -> sk_socket -> file )
1363
- gfp = GFP_USER | __GFP_NOWARN ;
1364
- kaddrs = kmalloc (addrs_size , gfp );
1365
- if (unlikely (!kaddrs ))
1366
- return - ENOMEM ;
1367
-
1368
- if (__copy_from_user (kaddrs , addrs , addrs_size )) {
1369
- err = - EFAULT ;
1370
- } else {
1371
- err = __sctp_connect (sk , kaddrs , addrs_size , assoc_id );
1372
- }
1332
+ kaddrs = vmemdup_user (addrs , addrs_size );
1333
+ if (unlikely (IS_ERR (kaddrs )))
1334
+ return PTR_ERR (kaddrs );
1373
1335
1374
- kfree (kaddrs );
1336
+ err = __sctp_connect (sk , kaddrs , addrs_size , assoc_id );
1337
+ kvfree (kaddrs );
1375
1338
1376
1339
return err ;
1377
1340
}
0 commit comments