aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/ipv6.c5
-rw-r--r--net/sctp/outqueue.c3
-rw-r--r--net/sctp/protocol.c4
-rw-r--r--net/sctp/sm_make_chunk.c29
-rw-r--r--net/sctp/sm_sideeffect.c3
-rw-r--r--net/sctp/sm_statefuns.c23
-rw-r--r--net/sctp/socket.c5
-rw-r--r--net/sctp/ulpevent.c2
8 files changed, 63 insertions, 11 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index b1e05d719f9b..85f1495e0edc 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -110,8 +110,9 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
110 spin_lock_bh(&sctp_local_addr_lock); 110 spin_lock_bh(&sctp_local_addr_lock);
111 list_for_each_entry_safe(addr, temp, 111 list_for_each_entry_safe(addr, temp,
112 &sctp_local_addr_list, list) { 112 &sctp_local_addr_list, list) {
113 if (ipv6_addr_equal(&addr->a.v6.sin6_addr, 113 if (addr->a.sa.sa_family == AF_INET6 &&
114 &ifa->addr)) { 114 ipv6_addr_equal(&addr->a.v6.sin6_addr,
115 &ifa->addr)) {
115 found = 1; 116 found = 1;
116 addr->valid = 0; 117 addr->valid = 0;
117 list_del_rcu(&addr->list); 118 list_del_rcu(&addr->list);
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1bb3c5c35d2a..c0714469233c 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -793,6 +793,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
793 break; 793 break;
794 794
795 case SCTP_CID_ABORT: 795 case SCTP_CID_ABORT:
796 if (sctp_test_T_bit(chunk)) {
797 packet->vtag = asoc->c.my_vtag;
798 }
796 case SCTP_CID_SACK: 799 case SCTP_CID_SACK:
797 case SCTP_CID_HEARTBEAT: 800 case SCTP_CID_HEARTBEAT:
798 case SCTP_CID_HEARTBEAT_ACK: 801 case SCTP_CID_HEARTBEAT_ACK:
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f90091a1b9ce..c2dd65d9f38d 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -647,7 +647,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
647 spin_lock_bh(&sctp_local_addr_lock); 647 spin_lock_bh(&sctp_local_addr_lock);
648 list_for_each_entry_safe(addr, temp, 648 list_for_each_entry_safe(addr, temp,
649 &sctp_local_addr_list, list) { 649 &sctp_local_addr_list, list) {
650 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { 650 if (addr->a.sa.sa_family == AF_INET &&
651 addr->a.v4.sin_addr.s_addr ==
652 ifa->ifa_local) {
651 found = 1; 653 found = 1;
652 addr->valid = 0; 654 addr->valid = 0;
653 list_del_rcu(&addr->list); 655 list_del_rcu(&addr->list);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 578630e8e00d..36ebb392472e 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1982,7 +1982,10 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
1982 struct sctp_chunk *chunk, 1982 struct sctp_chunk *chunk,
1983 struct sctp_chunk **err_chunk) 1983 struct sctp_chunk **err_chunk)
1984{ 1984{
1985 struct sctp_hmac_algo_param *hmacs;
1985 int retval = SCTP_IERROR_NO_ERROR; 1986 int retval = SCTP_IERROR_NO_ERROR;
1987 __u16 n_elt, id = 0;
1988 int i;
1986 1989
1987 /* FIXME - This routine is not looking at each parameter per the 1990 /* FIXME - This routine is not looking at each parameter per the
1988 * chunk type, i.e., unrecognized parameters should be further 1991 * chunk type, i.e., unrecognized parameters should be further
@@ -2056,9 +2059,29 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
2056 break; 2059 break;
2057 2060
2058 case SCTP_PARAM_HMAC_ALGO: 2061 case SCTP_PARAM_HMAC_ALGO:
2059 if (sctp_auth_enable) 2062 if (!sctp_auth_enable)
2060 break; 2063 goto fallthrough;
2061 /* Fall Through */ 2064
2065 hmacs = (struct sctp_hmac_algo_param *)param.p;
2066 n_elt = (ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) >> 1;
2067
2068 /* SCTP-AUTH: Section 6.1
2069 * The HMAC algorithm based on SHA-1 MUST be supported and
2070 * included in the HMAC-ALGO parameter.
2071 */
2072 for (i = 0; i < n_elt; i++) {
2073 id = ntohs(hmacs->hmac_ids[i]);
2074
2075 if (id == SCTP_AUTH_HMAC_ID_SHA1)
2076 break;
2077 }
2078
2079 if (id != SCTP_AUTH_HMAC_ID_SHA1) {
2080 sctp_process_inv_paramlength(asoc, param.p, chunk,
2081 err_chunk);
2082 retval = SCTP_IERROR_ABORT;
2083 }
2084 break;
2062fallthrough: 2085fallthrough:
2063 default: 2086 default:
2064 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n", 2087 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 28eb38eb6083..a4763fd24fd8 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1536,6 +1536,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1536 error = sctp_auth_asoc_init_active_key(asoc, 1536 error = sctp_auth_asoc_init_active_key(asoc,
1537 GFP_ATOMIC); 1537 GFP_ATOMIC);
1538 break; 1538 break;
1539 case SCTP_CMD_UPDATE_INITTAG:
1540 asoc->peer.i.init_tag = cmd->obj.u32;
1541 break;
1539 1542
1540 default: 1543 default:
1541 printk(KERN_WARNING "Impossible command: %u, %p\n", 1544 printk(KERN_WARNING "Impossible command: %u, %p\n",
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index f2ed6473feef..07194c2a32df 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4144,6 +4144,24 @@ static sctp_disposition_t sctp_sf_abort_violation(
4144 goto nomem; 4144 goto nomem;
4145 4145
4146 if (asoc) { 4146 if (asoc) {
4147 /* Treat INIT-ACK as a special case during COOKIE-WAIT. */
4148 if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
4149 !asoc->peer.i.init_tag) {
4150 sctp_initack_chunk_t *initack;
4151
4152 initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
4153 if (!sctp_chunk_length_valid(chunk,
4154 sizeof(sctp_initack_chunk_t)))
4155 abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
4156 else {
4157 unsigned int inittag;
4158
4159 inittag = ntohl(initack->init_hdr.init_tag);
4160 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
4161 SCTP_U32(inittag));
4162 }
4163 }
4164
4147 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 4165 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4148 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4166 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4149 4167
@@ -4349,6 +4367,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4349 sctp_cmd_seq_t *commands) 4367 sctp_cmd_seq_t *commands)
4350{ 4368{
4351 struct sctp_chunk *repl; 4369 struct sctp_chunk *repl;
4370 struct sctp_association* my_asoc;
4352 4371
4353 /* The comment below says that we enter COOKIE-WAIT AFTER 4372 /* The comment below says that we enter COOKIE-WAIT AFTER
4354 * sending the INIT, but that doesn't actually work in our 4373 * sending the INIT, but that doesn't actually work in our
@@ -4372,8 +4391,8 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4372 /* Cast away the const modifier, as we want to just 4391 /* Cast away the const modifier, as we want to just
4373 * rerun it through as a sideffect. 4392 * rerun it through as a sideffect.
4374 */ 4393 */
4375 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, 4394 my_asoc = (struct sctp_association *)asoc;
4376 SCTP_ASOC((struct sctp_association *) asoc)); 4395 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
4377 4396
4378 /* Choose transport for INIT. */ 4397 /* Choose transport for INIT. */
4379 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT, 4398 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d994d822900d..998e63a31311 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5868,11 +5868,12 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
5868 sctp_cmsgs_t *cmsgs) 5868 sctp_cmsgs_t *cmsgs)
5869{ 5869{
5870 struct cmsghdr *cmsg; 5870 struct cmsghdr *cmsg;
5871 struct msghdr *my_msg = (struct msghdr *)msg;
5871 5872
5872 for (cmsg = CMSG_FIRSTHDR(msg); 5873 for (cmsg = CMSG_FIRSTHDR(msg);
5873 cmsg != NULL; 5874 cmsg != NULL;
5874 cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) { 5875 cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
5875 if (!CMSG_OK(msg, cmsg)) 5876 if (!CMSG_OK(my_msg, cmsg))
5876 return -EINVAL; 5877 return -EINVAL;
5877 5878
5878 /* Should we parse this header or ignore? */ 5879 /* Should we parse this header or ignore? */
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index b43f1f110f87..ce6cda6b6994 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -859,7 +859,7 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event)
859 union sctp_notification *notification; 859 union sctp_notification *notification;
860 struct sk_buff *skb; 860 struct sk_buff *skb;
861 861
862 skb = sctp_event2skb((struct sctp_ulpevent *)event); 862 skb = sctp_event2skb(event);
863 notification = (union sctp_notification *) skb->data; 863 notification = (union sctp_notification *) skb->data;
864 return notification->sn_header.sn_type; 864 return notification->sn_header.sn_type;
865} 865}