aboutsummaryrefslogtreecommitdiff
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c9
-rw-r--r--net/sctp/auth.c3
-rw-r--r--net/sctp/output.c3
-rw-r--r--net/sctp/sm_make_chunk.c15
-rw-r--r--net/sctp/socket.c8
5 files changed, 24 insertions, 14 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 8472b8b349c..abd51cef241 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -599,11 +599,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
/* Check to see if this is a duplicate. */
peer = sctp_assoc_lookup_paddr(asoc, addr);
if (peer) {
+ /* An UNKNOWN state is only set on transports added by
+ * user in sctp_connectx() call. Such transports should be
+ * considered CONFIRMED per RFC 4960, Section 5.4.
+ */
if (peer->state == SCTP_UNKNOWN) {
- if (peer_state == SCTP_ACTIVE)
- peer->state = SCTP_ACTIVE;
- if (peer_state == SCTP_UNCONFIRMED)
- peer->state = SCTP_UNCONFIRMED;
+ peer->state = SCTP_ACTIVE;
}
return peer;
}
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 1fcb4cf2f4c..52db5f60daa 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -786,6 +786,9 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
for (i = 0; i < hmacs->shmac_num_idents; i++) {
id = hmacs->shmac_idents[i];
+ if (id > SCTP_AUTH_HMAC_ID_MAX)
+ return -EOPNOTSUPP;
+
if (SCTP_AUTH_HMAC_ID_SHA1 == id)
has_sha1 = 1;
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 0dc4a7dfb23..225c7123c41 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -533,7 +533,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
crc32 = sctp_end_cksum(crc32);
- }
+ } else
+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
/* 3) Put the resultant value into the checksum field in the
* common header, and leave the rest of the bits unchanged.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index e8ca4e54981..b599cbba4fb 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1886,11 +1886,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
/* if the peer reports AUTH, assume that he
* supports AUTH.
*/
- asoc->peer.auth_capable = 1;
+ if (sctp_auth_enable)
+ asoc->peer.auth_capable = 1;
break;
case SCTP_CID_ASCONF:
case SCTP_CID_ASCONF_ACK:
- asoc->peer.asconf_capable = 1;
+ if (sctp_addip_enable)
+ asoc->peer.asconf_capable = 1;
break;
default:
break;
@@ -2319,12 +2321,10 @@ clean_up:
/* Release the transport structures. */
list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
transport = list_entry(pos, struct sctp_transport, transports);
- list_del_init(pos);
- sctp_transport_free(transport);
+ if (transport->state != SCTP_ACTIVE)
+ sctp_assoc_rm_peer(asoc, transport);
}
- asoc->peer.transport_count = 0;
-
nomem:
return 0;
}
@@ -2460,6 +2460,9 @@ do_addr_param:
break;
case SCTP_PARAM_SET_PRIMARY:
+ if (!sctp_addip_enable)
+ goto fall_through;
+
addr_param = param.v + sizeof(sctp_addip_param_t);
af = sctp_get_af_specific(param_type2af(param.p->type));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index afa952e726d..5ffb9dec1c3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3086,6 +3086,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
int optlen)
{
struct sctp_hmacalgo *hmacs;
+ u32 idents;
int err;
if (!sctp_auth_enable)
@@ -3103,8 +3104,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
goto out;
}
- if (hmacs->shmac_num_idents == 0 ||
- hmacs->shmac_num_idents > SCTP_AUTH_NUM_HMACS) {
+ idents = hmacs->shmac_num_idents;
+ if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS ||
+ (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) {
err = -EINVAL;
goto out;
}
@@ -3144,7 +3146,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
goto out;
}
- if (authkey->sca_keylength > optlen) {
+ if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) {
ret = -EINVAL;
goto out;
}