aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sctp/socket.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bf705ba97231..3a95fcb17a9e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1276,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
1276} 1276}
1277 1277
1278/* 1278/*
1279 * New (hopefully final) interface for the API. The option buffer is used 1279 * New (hopefully final) interface for the API.
1280 * both for the returned association id and the addresses. 1280 * We use the sctp_getaddrs_old structure so that use-space library
1281 * can avoid any unnecessary allocations. The only defferent part
1282 * is that we store the actual length of the address buffer into the
1283 * addrs_num structure member. That way we can re-use the existing
1284 * code.
1281 */ 1285 */
1282SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, 1286SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
1283 char __user *optval, 1287 char __user *optval,
1284 int __user *optlen) 1288 int __user *optlen)
1285{ 1289{
1290 struct sctp_getaddrs_old param;
1286 sctp_assoc_t assoc_id = 0; 1291 sctp_assoc_t assoc_id = 0;
1287 int err = 0; 1292 int err = 0;
1288 1293
1289 if (len < sizeof(assoc_id)) 1294 if (len < sizeof(param))
1290 return -EINVAL; 1295 return -EINVAL;
1291 1296
1297 if (copy_from_user(&param, optval, sizeof(param)))
1298 return -EFAULT;
1299
1292 err = __sctp_setsockopt_connectx(sk, 1300 err = __sctp_setsockopt_connectx(sk,
1293 (struct sockaddr __user *)(optval + sizeof(assoc_id)), 1301 (struct sockaddr __user *)param.addrs,
1294 len - sizeof(assoc_id), &assoc_id); 1302 param.addr_num, &assoc_id);
1295 1303
1296 if (err == 0 || err == -EINPROGRESS) { 1304 if (err == 0 || err == -EINPROGRESS) {
1297 if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) 1305 if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))