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 036bfcc8d15b..e45e44c60635 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 213c2e2926a9..a7ba9e146dff 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -794,6 +794,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
794 break; 794 break;
795 795
796 case SCTP_CID_ABORT: 796 case SCTP_CID_ABORT:
797 if (sctp_test_T_bit(chunk)) {
798 packet->vtag = asoc->c.my_vtag;
799 }
797 case SCTP_CID_SACK: 800 case SCTP_CID_SACK:
798 case SCTP_CID_HEARTBEAT: 801 case SCTP_CID_HEARTBEAT:
799 case SCTP_CID_HEARTBEAT_ACK: 802 case SCTP_CID_HEARTBEAT_ACK:
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b34437fdea26..0ec234b762c2 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -650,7 +650,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
650 spin_lock_bh(&sctp_local_addr_lock); 650 spin_lock_bh(&sctp_local_addr_lock);
651 list_for_each_entry_safe(addr, temp, 651 list_for_each_entry_safe(addr, temp,
652 &sctp_local_addr_list, list) { 652 &sctp_local_addr_list, list) {
653 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { 653 if (addr->a.sa.sa_family == AF_INET &&
654 addr->a.v4.sin_addr.s_addr ==
655 ifa->ifa_local) {
654 found = 1; 656 found = 1;
655 addr->valid = 0; 657 addr->valid = 0;
656 list_del_rcu(&addr->list); 658 list_del_rcu(&addr->list);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 0679bddf3a95..81b606424e12 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 13beed263e31..23a9f1a95b7d 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1529,6 +1529,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1529 error = sctp_auth_asoc_init_active_key(asoc, 1529 error = sctp_auth_asoc_init_active_key(asoc,
1530 GFP_ATOMIC); 1530 GFP_ATOMIC);
1531 break; 1531 break;
1532 case SCTP_CMD_UPDATE_INITTAG:
1533 asoc->peer.i.init_tag = cmd->obj.u32;
1534 break;
1532 1535
1533 default: 1536 default:
1534 printk(KERN_WARNING "Impossible command: %u, %p\n", 1537 printk(KERN_WARNING "Impossible command: %u, %p\n",
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 622284805500..0c9d5a6950fe 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4138,6 +4138,24 @@ static sctp_disposition_t sctp_sf_abort_violation(
4138 goto nomem; 4138 goto nomem;
4139 4139
4140 if (asoc) { 4140 if (asoc) {
4141 /* Treat INIT-ACK as a special case during COOKIE-WAIT. */
4142 if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
4143 !asoc->peer.i.init_tag) {
4144 sctp_initack_chunk_t *initack;
4145
4146 initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
4147 if (!sctp_chunk_length_valid(chunk,
4148 sizeof(sctp_initack_chunk_t)))
4149 abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
4150 else {
4151 unsigned int inittag;
4152
4153 inittag = ntohl(initack->init_hdr.init_tag);
4154 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
4155 SCTP_U32(inittag));
4156 }
4157 }
4158
4141 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 4159 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4142 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4160 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4143 4161
@@ -4343,6 +4361,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4343 sctp_cmd_seq_t *commands) 4361 sctp_cmd_seq_t *commands)
4344{ 4362{
4345 struct sctp_chunk *repl; 4363 struct sctp_chunk *repl;
4364 struct sctp_association* my_asoc;
4346 4365
4347 /* The comment below says that we enter COOKIE-WAIT AFTER 4366 /* The comment below says that we enter COOKIE-WAIT AFTER
4348 * sending the INIT, but that doesn't actually work in our 4367 * sending the INIT, but that doesn't actually work in our
@@ -4366,8 +4385,8 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4366 /* Cast away the const modifier, as we want to just 4385 /* Cast away the const modifier, as we want to just
4367 * rerun it through as a sideffect. 4386 * rerun it through as a sideffect.
4368 */ 4387 */
4369 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, 4388 my_asoc = (struct sctp_association *)asoc;
4370 SCTP_ASOC((struct sctp_association *) asoc)); 4389 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
4371 4390
4372 /* Choose transport for INIT. */ 4391 /* Choose transport for INIT. */
4373 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT, 4392 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 8c90289ba400..e7e3baf7009e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5848,11 +5848,12 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
5848 sctp_cmsgs_t *cmsgs) 5848 sctp_cmsgs_t *cmsgs)
5849{ 5849{
5850 struct cmsghdr *cmsg; 5850 struct cmsghdr *cmsg;
5851 struct msghdr *my_msg = (struct msghdr *)msg;
5851 5852
5852 for (cmsg = CMSG_FIRSTHDR(msg); 5853 for (cmsg = CMSG_FIRSTHDR(msg);
5853 cmsg != NULL; 5854 cmsg != NULL;
5854 cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) { 5855 cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
5855 if (!CMSG_OK(msg, cmsg)) 5856 if (!CMSG_OK(my_msg, cmsg))
5856 return -EINVAL; 5857 return -EINVAL;
5857 5858
5858 /* Should we parse this header or ignore? */ 5859 /* 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}