diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/ipv6.c | 5 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 3 | ||||
-rw-r--r-- | net/sctp/protocol.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 29 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 3 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 23 | ||||
-rw-r--r-- | net/sctp/socket.c | 5 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 2 |
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; | ||
2062 | fallthrough: | 2085 | fallthrough: |
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 | } |