summaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c70
1 files changed, 66 insertions, 4 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 7a10ae3c3d82..2a2e094560de 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1046,6 +1046,12 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1046 /* Do the work. */ 1046 /* Do the work. */
1047 switch (op) { 1047 switch (op) {
1048 case SCTP_BINDX_ADD_ADDR: 1048 case SCTP_BINDX_ADD_ADDR:
1049 /* Allow security module to validate bindx addresses. */
1050 err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_BINDX_ADD,
1051 (struct sockaddr *)kaddrs,
1052 addrs_size);
1053 if (err)
1054 goto out;
1049 err = sctp_bindx_add(sk, kaddrs, addrcnt); 1055 err = sctp_bindx_add(sk, kaddrs, addrcnt);
1050 if (err) 1056 if (err)
1051 goto out; 1057 goto out;
@@ -1255,6 +1261,7 @@ static int __sctp_connect(struct sock *sk,
1255 1261
1256 if (assoc_id) 1262 if (assoc_id)
1257 *assoc_id = asoc->assoc_id; 1263 *assoc_id = asoc->assoc_id;
1264
1258 err = sctp_wait_for_connect(asoc, &timeo); 1265 err = sctp_wait_for_connect(asoc, &timeo);
1259 /* Note: the asoc may be freed after the return of 1266 /* Note: the asoc may be freed after the return of
1260 * sctp_wait_for_connect. 1267 * sctp_wait_for_connect.
@@ -1350,7 +1357,16 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
1350 if (unlikely(IS_ERR(kaddrs))) 1357 if (unlikely(IS_ERR(kaddrs)))
1351 return PTR_ERR(kaddrs); 1358 return PTR_ERR(kaddrs);
1352 1359
1360 /* Allow security module to validate connectx addresses. */
1361 err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_CONNECTX,
1362 (struct sockaddr *)kaddrs,
1363 addrs_size);
1364 if (err)
1365 goto out_free;
1366
1353 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id); 1367 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
1368
1369out_free:
1354 kvfree(kaddrs); 1370 kvfree(kaddrs);
1355 1371
1356 return err; 1372 return err;
@@ -1680,6 +1696,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
1680 struct sctp_association *asoc; 1696 struct sctp_association *asoc;
1681 enum sctp_scope scope; 1697 enum sctp_scope scope;
1682 struct cmsghdr *cmsg; 1698 struct cmsghdr *cmsg;
1699 struct sctp_af *af;
1683 int err; 1700 int err;
1684 1701
1685 *tp = NULL; 1702 *tp = NULL;
@@ -1705,6 +1722,21 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
1705 1722
1706 scope = sctp_scope(daddr); 1723 scope = sctp_scope(daddr);
1707 1724
1725 /* Label connection socket for first association 1-to-many
1726 * style for client sequence socket()->sendmsg(). This
1727 * needs to be done before sctp_assoc_add_peer() as that will
1728 * set up the initial packet that needs to account for any
1729 * security ip options (CIPSO/CALIPSO) added to the packet.
1730 */
1731 af = sctp_get_af_specific(daddr->sa.sa_family);
1732 if (!af)
1733 return -EINVAL;
1734 err = security_sctp_bind_connect(sk, SCTP_SENDMSG_CONNECT,
1735 (struct sockaddr *)daddr,
1736 af->sockaddr_len);
1737 if (err < 0)
1738 return err;
1739
1708 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); 1740 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
1709 if (!asoc) 1741 if (!asoc)
1710 return -ENOMEM; 1742 return -ENOMEM;
@@ -2932,6 +2964,8 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2932{ 2964{
2933 struct sctp_prim prim; 2965 struct sctp_prim prim;
2934 struct sctp_transport *trans; 2966 struct sctp_transport *trans;
2967 struct sctp_af *af;
2968 int err;
2935 2969
2936 if (optlen != sizeof(struct sctp_prim)) 2970 if (optlen != sizeof(struct sctp_prim))
2937 return -EINVAL; 2971 return -EINVAL;
@@ -2939,6 +2973,17 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2939 if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) 2973 if (copy_from_user(&prim, optval, sizeof(struct sctp_prim)))
2940 return -EFAULT; 2974 return -EFAULT;
2941 2975
2976 /* Allow security module to validate address but need address len. */
2977 af = sctp_get_af_specific(prim.ssp_addr.ss_family);
2978 if (!af)
2979 return -EINVAL;
2980
2981 err = security_sctp_bind_connect(sk, SCTP_PRIMARY_ADDR,
2982 (struct sockaddr *)&prim.ssp_addr,
2983 af->sockaddr_len);
2984 if (err)
2985 return err;
2986
2942 trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id); 2987 trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id);
2943 if (!trans) 2988 if (!trans)
2944 return -EINVAL; 2989 return -EINVAL;
@@ -3161,6 +3206,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsign
3161static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) 3206static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
3162{ 3207{
3163 struct sctp_sock *sp = sctp_sk(sk); 3208 struct sctp_sock *sp = sctp_sk(sk);
3209 struct sctp_af *af = sp->pf->af;
3164 struct sctp_assoc_value params; 3210 struct sctp_assoc_value params;
3165 struct sctp_association *asoc; 3211 struct sctp_association *asoc;
3166 int val; 3212 int val;
@@ -3185,7 +3231,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
3185 if (val) { 3231 if (val) {
3186 int min_len, max_len; 3232 int min_len, max_len;
3187 3233
3188 min_len = SCTP_DEFAULT_MINSEGMENT - sp->pf->af->net_header_len; 3234 min_len = SCTP_DEFAULT_MINSEGMENT - af->net_header_len;
3235 min_len -= af->ip_options_len(sk);
3189 min_len -= sizeof(struct sctphdr) + 3236 min_len -= sizeof(struct sctphdr) +
3190 sizeof(struct sctp_data_chunk); 3237 sizeof(struct sctp_data_chunk);
3191 3238
@@ -3198,7 +3245,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
3198 asoc = sctp_id2assoc(sk, params.assoc_id); 3245 asoc = sctp_id2assoc(sk, params.assoc_id);
3199 if (asoc) { 3246 if (asoc) {
3200 if (val == 0) { 3247 if (val == 0) {
3201 val = asoc->pathmtu - sp->pf->af->net_header_len; 3248 val = asoc->pathmtu - af->net_header_len;
3249 val -= af->ip_options_len(sk);
3202 val -= sizeof(struct sctphdr) + 3250 val -= sizeof(struct sctphdr) +
3203 sctp_datachk_len(&asoc->stream); 3251 sctp_datachk_len(&asoc->stream);
3204 } 3252 }
@@ -3267,6 +3315,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
3267 if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) 3315 if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
3268 return -EADDRNOTAVAIL; 3316 return -EADDRNOTAVAIL;
3269 3317
3318 /* Allow security module to validate address. */
3319 err = security_sctp_bind_connect(sk, SCTP_SET_PEER_PRIMARY_ADDR,
3320 (struct sockaddr *)&prim.sspp_addr,
3321 af->sockaddr_len);
3322 if (err)
3323 return err;
3324
3270 /* Create an ASCONF chunk with SET_PRIMARY parameter */ 3325 /* Create an ASCONF chunk with SET_PRIMARY parameter */
3271 chunk = sctp_make_asconf_set_prim(asoc, 3326 chunk = sctp_make_asconf_set_prim(asoc,
3272 (union sctp_addr *)&prim.sspp_addr); 3327 (union sctp_addr *)&prim.sspp_addr);
@@ -5140,9 +5195,11 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
5140 sctp_copy_sock(sock->sk, sk, asoc); 5195 sctp_copy_sock(sock->sk, sk, asoc);
5141 5196
5142 /* Make peeled-off sockets more like 1-1 accepted sockets. 5197 /* Make peeled-off sockets more like 1-1 accepted sockets.
5143 * Set the daddr and initialize id to something more random 5198 * Set the daddr and initialize id to something more random and also
5199 * copy over any ip options.
5144 */ 5200 */
5145 sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk); 5201 sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk);
5202 sp->pf->copy_ip_options(sk, sock->sk);
5146 5203
5147 /* Populate the fields of the newsk from the oldsk and migrate the 5204 /* Populate the fields of the newsk from the oldsk and migrate the
5148 * asoc to the newsk. 5205 * asoc to the newsk.
@@ -8465,6 +8522,8 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
8465{ 8522{
8466 struct inet_sock *inet = inet_sk(sk); 8523 struct inet_sock *inet = inet_sk(sk);
8467 struct inet_sock *newinet; 8524 struct inet_sock *newinet;
8525 struct sctp_sock *sp = sctp_sk(sk);
8526 struct sctp_endpoint *ep = sp->ep;
8468 8527
8469 newsk->sk_type = sk->sk_type; 8528 newsk->sk_type = sk->sk_type;
8470 newsk->sk_bound_dev_if = sk->sk_bound_dev_if; 8529 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
@@ -8507,7 +8566,10 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
8507 if (newsk->sk_flags & SK_FLAGS_TIMESTAMP) 8566 if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
8508 net_enable_timestamp(); 8567 net_enable_timestamp();
8509 8568
8510 security_sk_clone(sk, newsk); 8569 /* Set newsk security attributes from orginal sk and connection
8570 * security attribute from ep.
8571 */
8572 security_sctp_sk_clone(ep, sk, newsk);
8511} 8573}
8512 8574
8513static inline void sctp_copy_descendant(struct sock *sk_to, 8575static inline void sctp_copy_descendant(struct sock *sk_to,