summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorRichard Haines <richard_c_haines@btinternet.com>2018-02-13 15:56:24 -0500
committerPaul Moore <paul@paul-moore.com>2018-02-26 17:45:23 -0500
commit2277c7cd75e39783eeb7512a6c35f8b4abbe1039 (patch)
tree247a9b36acd431330a479ccdcb9b277f0b4d4973 /net/sctp
parentb7e10c25b839c0c7579b2b402afc9883c107e09f (diff)
sctp: Add LSM hooks
Add security hooks allowing security modules to exercise access control over SCTP. Signed-off-by: Richard Haines <richard_c_haines@btinternet.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_make_chunk.c12
-rw-r--r--net/sctp/sm_statefuns.c18
-rw-r--r--net/sctp/socket.c62
3 files changed, 91 insertions, 1 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index d01475f5f710..70274ae5ac6f 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3071,6 +3071,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
3071 if (af->is_any(&addr)) 3071 if (af->is_any(&addr))
3072 memcpy(&addr, &asconf->source, sizeof(addr)); 3072 memcpy(&addr, &asconf->source, sizeof(addr));
3073 3073
3074 if (security_sctp_bind_connect(asoc->ep->base.sk,
3075 SCTP_PARAM_ADD_IP,
3076 (struct sockaddr *)&addr,
3077 af->sockaddr_len))
3078 return SCTP_ERROR_REQ_REFUSED;
3079
3074 /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address 3080 /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
3075 * request and does not have the local resources to add this 3081 * request and does not have the local resources to add this
3076 * new address to the association, it MUST return an Error 3082 * new address to the association, it MUST return an Error
@@ -3137,6 +3143,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
3137 if (af->is_any(&addr)) 3143 if (af->is_any(&addr))
3138 memcpy(&addr.v4, sctp_source(asconf), sizeof(addr)); 3144 memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
3139 3145
3146 if (security_sctp_bind_connect(asoc->ep->base.sk,
3147 SCTP_PARAM_SET_PRIMARY,
3148 (struct sockaddr *)&addr,
3149 af->sockaddr_len))
3150 return SCTP_ERROR_REQ_REFUSED;
3151
3140 peer = sctp_assoc_lookup_paddr(asoc, &addr); 3152 peer = sctp_assoc_lookup_paddr(asoc, &addr);
3141 if (!peer) 3153 if (!peer)
3142 return SCTP_ERROR_DNS_FAILED; 3154 return SCTP_ERROR_DNS_FAILED;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index eb7905ffe5f2..42659ab68c38 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -321,6 +321,11 @@ enum sctp_disposition sctp_sf_do_5_1B_init(struct net *net,
321 struct sctp_packet *packet; 321 struct sctp_packet *packet;
322 int len; 322 int len;
323 323
324 /* Update socket peer label if first association. */
325 if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
326 chunk->skb))
327 return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
328
324 /* 6.10 Bundling 329 /* 6.10 Bundling
325 * An endpoint MUST NOT bundle INIT, INIT ACK or 330 * An endpoint MUST NOT bundle INIT, INIT ACK or
326 * SHUTDOWN COMPLETE with any other chunks. 331 * SHUTDOWN COMPLETE with any other chunks.
@@ -908,6 +913,9 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
908 */ 913 */
909 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL()); 914 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
910 915
916 /* Set peer label for connection. */
917 security_inet_conn_established(ep->base.sk, chunk->skb);
918
911 /* RFC 2960 5.1 Normal Establishment of an Association 919 /* RFC 2960 5.1 Normal Establishment of an Association
912 * 920 *
913 * E) Upon reception of the COOKIE ACK, endpoint "A" will move 921 * E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -1436,6 +1444,11 @@ static enum sctp_disposition sctp_sf_do_unexpected_init(
1436 struct sctp_packet *packet; 1444 struct sctp_packet *packet;
1437 int len; 1445 int len;
1438 1446
1447 /* Update socket peer label if first association. */
1448 if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
1449 chunk->skb))
1450 return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
1451
1439 /* 6.10 Bundling 1452 /* 6.10 Bundling
1440 * An endpoint MUST NOT bundle INIT, INIT ACK or 1453 * An endpoint MUST NOT bundle INIT, INIT ACK or
1441 * SHUTDOWN COMPLETE with any other chunks. 1454 * SHUTDOWN COMPLETE with any other chunks.
@@ -2106,6 +2119,11 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
2106 } 2119 }
2107 } 2120 }
2108 2121
2122 /* Update socket peer label if first association. */
2123 if (security_sctp_assoc_request((struct sctp_endpoint *)ep,
2124 chunk->skb))
2125 return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
2126
2109 /* Set temp so that it won't be added into hashtable */ 2127 /* Set temp so that it won't be added into hashtable */
2110 new_asoc->temp = 1; 2128 new_asoc->temp = 1;
2111 2129
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index eb55c63d1990..73b34a6b5b09 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1043,6 +1043,12 @@ static int sctp_setsockopt_bindx(struct sock *sk,
1043 /* Do the work. */ 1043 /* Do the work. */
1044 switch (op) { 1044 switch (op) {
1045 case SCTP_BINDX_ADD_ADDR: 1045 case SCTP_BINDX_ADD_ADDR:
1046 /* Allow security module to validate bindx addresses. */
1047 err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_BINDX_ADD,
1048 (struct sockaddr *)kaddrs,
1049 addrs_size);
1050 if (err)
1051 goto out;
1046 err = sctp_bindx_add(sk, kaddrs, addrcnt); 1052 err = sctp_bindx_add(sk, kaddrs, addrcnt);
1047 if (err) 1053 if (err)
1048 goto out; 1054 goto out;
@@ -1252,6 +1258,7 @@ static int __sctp_connect(struct sock *sk,
1252 1258
1253 if (assoc_id) 1259 if (assoc_id)
1254 *assoc_id = asoc->assoc_id; 1260 *assoc_id = asoc->assoc_id;
1261
1255 err = sctp_wait_for_connect(asoc, &timeo); 1262 err = sctp_wait_for_connect(asoc, &timeo);
1256 /* Note: the asoc may be freed after the return of 1263 /* Note: the asoc may be freed after the return of
1257 * sctp_wait_for_connect. 1264 * sctp_wait_for_connect.
@@ -1347,7 +1354,16 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
1347 if (unlikely(IS_ERR(kaddrs))) 1354 if (unlikely(IS_ERR(kaddrs)))
1348 return PTR_ERR(kaddrs); 1355 return PTR_ERR(kaddrs);
1349 1356
1357 /* Allow security module to validate connectx addresses. */
1358 err = security_sctp_bind_connect(sk, SCTP_SOCKOPT_CONNECTX,
1359 (struct sockaddr *)kaddrs,
1360 addrs_size);
1361 if (err)
1362 goto out_free;
1363
1350 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id); 1364 err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
1365
1366out_free:
1351 kvfree(kaddrs); 1367 kvfree(kaddrs);
1352 1368
1353 return err; 1369 return err;
@@ -1615,6 +1631,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
1615 struct sctp_transport *transport, *chunk_tp; 1631 struct sctp_transport *transport, *chunk_tp;
1616 struct sctp_chunk *chunk; 1632 struct sctp_chunk *chunk;
1617 union sctp_addr to; 1633 union sctp_addr to;
1634 struct sctp_af *af;
1618 struct sockaddr *msg_name = NULL; 1635 struct sockaddr *msg_name = NULL;
1619 struct sctp_sndrcvinfo default_sinfo; 1636 struct sctp_sndrcvinfo default_sinfo;
1620 struct sctp_sndrcvinfo *sinfo; 1637 struct sctp_sndrcvinfo *sinfo;
@@ -1844,6 +1861,24 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
1844 } 1861 }
1845 1862
1846 scope = sctp_scope(&to); 1863 scope = sctp_scope(&to);
1864
1865 /* Label connection socket for first association 1-to-many
1866 * style for client sequence socket()->sendmsg(). This
1867 * needs to be done before sctp_assoc_add_peer() as that will
1868 * set up the initial packet that needs to account for any
1869 * security ip options (CIPSO/CALIPSO) added to the packet.
1870 */
1871 af = sctp_get_af_specific(to.sa.sa_family);
1872 if (!af) {
1873 err = -EINVAL;
1874 goto out_unlock;
1875 }
1876 err = security_sctp_bind_connect(sk, SCTP_SENDMSG_CONNECT,
1877 (struct sockaddr *)&to,
1878 af->sockaddr_len);
1879 if (err < 0)
1880 goto out_unlock;
1881
1847 new_asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); 1882 new_asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
1848 if (!new_asoc) { 1883 if (!new_asoc) {
1849 err = -ENOMEM; 1884 err = -ENOMEM;
@@ -2909,6 +2944,8 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2909{ 2944{
2910 struct sctp_prim prim; 2945 struct sctp_prim prim;
2911 struct sctp_transport *trans; 2946 struct sctp_transport *trans;
2947 struct sctp_af *af;
2948 int err;
2912 2949
2913 if (optlen != sizeof(struct sctp_prim)) 2950 if (optlen != sizeof(struct sctp_prim))
2914 return -EINVAL; 2951 return -EINVAL;
@@ -2916,6 +2953,17 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2916 if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) 2953 if (copy_from_user(&prim, optval, sizeof(struct sctp_prim)))
2917 return -EFAULT; 2954 return -EFAULT;
2918 2955
2956 /* Allow security module to validate address but need address len. */
2957 af = sctp_get_af_specific(prim.ssp_addr.ss_family);
2958 if (!af)
2959 return -EINVAL;
2960
2961 err = security_sctp_bind_connect(sk, SCTP_PRIMARY_ADDR,
2962 (struct sockaddr *)&prim.ssp_addr,
2963 af->sockaddr_len);
2964 if (err)
2965 return err;
2966
2919 trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id); 2967 trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id);
2920 if (!trans) 2968 if (!trans)
2921 return -EINVAL; 2969 return -EINVAL;
@@ -3247,6 +3295,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
3247 if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) 3295 if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
3248 return -EADDRNOTAVAIL; 3296 return -EADDRNOTAVAIL;
3249 3297
3298 /* Allow security module to validate address. */
3299 err = security_sctp_bind_connect(sk, SCTP_SET_PEER_PRIMARY_ADDR,
3300 (struct sockaddr *)&prim.sspp_addr,
3301 af->sockaddr_len);
3302 if (err)
3303 return err;
3304
3250 /* Create an ASCONF chunk with SET_PRIMARY parameter */ 3305 /* Create an ASCONF chunk with SET_PRIMARY parameter */
3251 chunk = sctp_make_asconf_set_prim(asoc, 3306 chunk = sctp_make_asconf_set_prim(asoc,
3252 (union sctp_addr *)&prim.sspp_addr); 3307 (union sctp_addr *)&prim.sspp_addr);
@@ -8346,6 +8401,8 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
8346{ 8401{
8347 struct inet_sock *inet = inet_sk(sk); 8402 struct inet_sock *inet = inet_sk(sk);
8348 struct inet_sock *newinet; 8403 struct inet_sock *newinet;
8404 struct sctp_sock *sp = sctp_sk(sk);
8405 struct sctp_endpoint *ep = sp->ep;
8349 8406
8350 newsk->sk_type = sk->sk_type; 8407 newsk->sk_type = sk->sk_type;
8351 newsk->sk_bound_dev_if = sk->sk_bound_dev_if; 8408 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
@@ -8388,7 +8445,10 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
8388 if (newsk->sk_flags & SK_FLAGS_TIMESTAMP) 8445 if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
8389 net_enable_timestamp(); 8446 net_enable_timestamp();
8390 8447
8391 security_sk_clone(sk, newsk); 8448 /* Set newsk security attributes from orginal sk and connection
8449 * security attribute from ep.
8450 */
8451 security_sctp_sk_clone(ep, sk, newsk);
8392} 8452}
8393 8453
8394static inline void sctp_copy_descendant(struct sock *sk_to, 8454static inline void sctp_copy_descendant(struct sock *sk_to,