aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sctp/socket.c59
1 files changed, 11 insertions, 48 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3204a9b29407..c2cccc9902d6 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -970,13 +970,6 @@ int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
970 * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() 970 * This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
971 * from userspace. 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 * On exit there is no need to do sockfd_put(), sys_setsockopt() does 973 * On exit there is no need to do sockfd_put(), sys_setsockopt() does
981 * it. 974 * it.
982 * 975 *
@@ -1006,25 +999,15 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1006 if (unlikely(addrs_size <= 0)) 999 if (unlikely(addrs_size <= 0))
1007 return -EINVAL; 1000 return -EINVAL;
1008 1001
1009 /* Check the user passed a healthy pointer. */ 1002 kaddrs = vmemdup_user(addrs, addrs_size);
1010 if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size))) 1003 if (unlikely(IS_ERR(kaddrs)))
1011 return -EFAULT; 1004 return PTR_ERR(kaddrs);
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 }
1022 1005
1023 /* Walk through the addrs buffer and count the number of addresses. */ 1006 /* Walk through the addrs buffer and count the number of addresses. */
1024 addr_buf = kaddrs; 1007 addr_buf = kaddrs;
1025 while (walk_size < addrs_size) { 1008 while (walk_size < addrs_size) {
1026 if (walk_size + sizeof(sa_family_t) > addrs_size) { 1009 if (walk_size + sizeof(sa_family_t) > addrs_size) {
1027 kfree(kaddrs); 1010 kvfree(kaddrs);
1028 return -EINVAL; 1011 return -EINVAL;
1029 } 1012 }
1030 1013
@@ -1035,7 +1018,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1035 * causes the address buffer to overflow return EINVAL. 1018 * causes the address buffer to overflow return EINVAL.
1036 */ 1019 */
1037 if (!af || (walk_size + af->sockaddr_len) > addrs_size) { 1020 if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
1038 kfree(kaddrs); 1021 kvfree(kaddrs);
1039 return -EINVAL; 1022 return -EINVAL;
1040 } 1023 }
1041 addrcnt++; 1024 addrcnt++;
@@ -1065,7 +1048,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1065 } 1048 }
1066 1049
1067out: 1050out:
1068 kfree(kaddrs); 1051 kvfree(kaddrs);
1069 1052
1070 return err; 1053 return err;
1071} 1054}
@@ -1323,13 +1306,6 @@ out_free:
1323 * land and invoking either sctp_connectx(). This is used for tunneling 1306 * land and invoking either sctp_connectx(). This is used for tunneling
1324 * the sctp_connectx() request through sctp_setsockopt() from userspace. 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 * On exit there is no need to do sockfd_put(), sys_setsockopt() does 1309 * On exit there is no need to do sockfd_put(), sys_setsockopt() does
1334 * it. 1310 * it.
1335 * 1311 *
@@ -1345,7 +1321,6 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
1345 sctp_assoc_t *assoc_id) 1321 sctp_assoc_t *assoc_id)
1346{ 1322{
1347 struct sockaddr *kaddrs; 1323 struct sockaddr *kaddrs;
1348 gfp_t gfp = GFP_KERNEL;
1349 int err = 0; 1324 int err = 0;
1350 1325
1351 pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n", 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 if (unlikely(addrs_size <= 0)) 1329 if (unlikely(addrs_size <= 0))
1355 return -EINVAL; 1330 return -EINVAL;
1356 1331
1357 /* Check the user passed a healthy pointer. */ 1332 kaddrs = vmemdup_user(addrs, addrs_size);
1358 if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size))) 1333 if (unlikely(IS_ERR(kaddrs)))
1359 return -EFAULT; 1334 return PTR_ERR(kaddrs);
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 }
1373 1335
1374 kfree(kaddrs); 1336 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
1337 kvfree(kaddrs);
1375 1338
1376 return err; 1339 return err;
1377} 1340}