diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/Kconfig | 4 | ||||
-rw-r--r-- | net/sctp/associola.c | 5 | ||||
-rw-r--r-- | net/sctp/auth.c | 31 | ||||
-rw-r--r-- | net/sctp/endpointola.c | 6 | ||||
-rw-r--r-- | net/sctp/input.c | 3 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 5 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 4 | ||||
-rw-r--r-- | net/sctp/probe.c | 27 | ||||
-rw-r--r-- | net/sctp/protocol.c | 2 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 31 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 6 | ||||
-rw-r--r-- | net/sctp/socket.c | 2 | ||||
-rw-r--r-- | net/sctp/transport.c | 20 |
13 files changed, 65 insertions, 81 deletions
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 7521d944c0fb..cf4852814e0c 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig | |||
@@ -3,8 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig IP_SCTP | 5 | menuconfig IP_SCTP |
6 | tristate "The SCTP Protocol (EXPERIMENTAL)" | 6 | tristate "The SCTP Protocol" |
7 | depends on INET && EXPERIMENTAL | 7 | depends on INET |
8 | depends on IPV6 || IPV6=n | 8 | depends on IPV6 || IPV6=n |
9 | select CRYPTO | 9 | select CRYPTO |
10 | select CRYPTO_HMAC | 10 | select CRYPTO_HMAC |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index b45ed1f96921..2f95f5a5145d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -434,8 +434,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
434 | * on our state. | 434 | * on our state. |
435 | */ | 435 | */ |
436 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) { | 436 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) { |
437 | if (timer_pending(&asoc->timers[i]) && | 437 | if (del_timer(&asoc->timers[i])) |
438 | del_timer(&asoc->timers[i])) | ||
439 | sctp_association_put(asoc); | 438 | sctp_association_put(asoc); |
440 | } | 439 | } |
441 | 440 | ||
@@ -1497,7 +1496,7 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len) | |||
1497 | 1496 | ||
1498 | /* Stop the SACK timer. */ | 1497 | /* Stop the SACK timer. */ |
1499 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; | 1498 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK]; |
1500 | if (timer_pending(timer) && del_timer(timer)) | 1499 | if (del_timer(timer)) |
1501 | sctp_association_put(asoc); | 1500 | sctp_association_put(asoc); |
1502 | } | 1501 | } |
1503 | } | 1502 | } |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 159b9bc5d633..ba1dfc3f8def 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -71,7 +71,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key) | |||
71 | return; | 71 | return; |
72 | 72 | ||
73 | if (atomic_dec_and_test(&key->refcnt)) { | 73 | if (atomic_dec_and_test(&key->refcnt)) { |
74 | kfree(key); | 74 | kzfree(key); |
75 | SCTP_DBG_OBJCNT_DEC(keys); | 75 | SCTP_DBG_OBJCNT_DEC(keys); |
76 | } | 76 | } |
77 | } | 77 | } |
@@ -200,27 +200,28 @@ static struct sctp_auth_bytes *sctp_auth_make_key_vector( | |||
200 | struct sctp_auth_bytes *new; | 200 | struct sctp_auth_bytes *new; |
201 | __u32 len; | 201 | __u32 len; |
202 | __u32 offset = 0; | 202 | __u32 offset = 0; |
203 | __u16 random_len, hmacs_len, chunks_len = 0; | ||
203 | 204 | ||
204 | len = ntohs(random->param_hdr.length) + ntohs(hmacs->param_hdr.length); | 205 | random_len = ntohs(random->param_hdr.length); |
205 | if (chunks) | 206 | hmacs_len = ntohs(hmacs->param_hdr.length); |
206 | len += ntohs(chunks->param_hdr.length); | 207 | if (chunks) |
208 | chunks_len = ntohs(chunks->param_hdr.length); | ||
207 | 209 | ||
208 | new = kmalloc(sizeof(struct sctp_auth_bytes) + len, gfp); | 210 | len = random_len + hmacs_len + chunks_len; |
211 | |||
212 | new = sctp_auth_create_key(len, gfp); | ||
209 | if (!new) | 213 | if (!new) |
210 | return NULL; | 214 | return NULL; |
211 | 215 | ||
212 | new->len = len; | 216 | memcpy(new->data, random, random_len); |
213 | 217 | offset += random_len; | |
214 | memcpy(new->data, random, ntohs(random->param_hdr.length)); | ||
215 | offset += ntohs(random->param_hdr.length); | ||
216 | 218 | ||
217 | if (chunks) { | 219 | if (chunks) { |
218 | memcpy(new->data + offset, chunks, | 220 | memcpy(new->data + offset, chunks, chunks_len); |
219 | ntohs(chunks->param_hdr.length)); | 221 | offset += chunks_len; |
220 | offset += ntohs(chunks->param_hdr.length); | ||
221 | } | 222 | } |
222 | 223 | ||
223 | memcpy(new->data + offset, hmacs, ntohs(hmacs->param_hdr.length)); | 224 | memcpy(new->data + offset, hmacs, hmacs_len); |
224 | 225 | ||
225 | return new; | 226 | return new; |
226 | } | 227 | } |
@@ -350,8 +351,8 @@ static struct sctp_auth_bytes *sctp_auth_asoc_create_secret( | |||
350 | secret = sctp_auth_asoc_set_secret(ep_key, first_vector, last_vector, | 351 | secret = sctp_auth_asoc_set_secret(ep_key, first_vector, last_vector, |
351 | gfp); | 352 | gfp); |
352 | out: | 353 | out: |
353 | kfree(local_key_vector); | 354 | sctp_auth_key_put(local_key_vector); |
354 | kfree(peer_key_vector); | 355 | sctp_auth_key_put(peer_key_vector); |
355 | 356 | ||
356 | return secret; | 357 | return secret; |
357 | } | 358 | } |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 17a001bac2cc..73aad3d16a45 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -151,9 +151,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
151 | ep->rcvbuf_policy = net->sctp.rcvbuf_policy; | 151 | ep->rcvbuf_policy = net->sctp.rcvbuf_policy; |
152 | 152 | ||
153 | /* Initialize the secret key used with cookie. */ | 153 | /* Initialize the secret key used with cookie. */ |
154 | get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE); | 154 | get_random_bytes(ep->secret_key, sizeof(ep->secret_key)); |
155 | ep->last_key = ep->current_key = 0; | ||
156 | ep->key_changed_at = jiffies; | ||
157 | 155 | ||
158 | /* SCTP-AUTH extensions*/ | 156 | /* SCTP-AUTH extensions*/ |
159 | INIT_LIST_HEAD(&ep->endpoint_shared_keys); | 157 | INIT_LIST_HEAD(&ep->endpoint_shared_keys); |
@@ -271,6 +269,8 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) | |||
271 | sctp_inq_free(&ep->base.inqueue); | 269 | sctp_inq_free(&ep->base.inqueue); |
272 | sctp_bind_addr_free(&ep->base.bind_addr); | 270 | sctp_bind_addr_free(&ep->base.bind_addr); |
273 | 271 | ||
272 | memset(ep->secret_key, 0, sizeof(ep->secret_key)); | ||
273 | |||
274 | /* Remove and free the port */ | 274 | /* Remove and free the port */ |
275 | if (sctp_sk(ep->base.sk)->bind_hash) | 275 | if (sctp_sk(ep->base.sk)->bind_hash) |
276 | sctp_put_port(ep->base.sk); | 276 | sctp_put_port(ep->base.sk); |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 8bd3c279427e..965bbbbe48d4 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -468,8 +468,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
468 | } else { | 468 | } else { |
469 | struct net *net = sock_net(sk); | 469 | struct net *net = sock_net(sk); |
470 | 470 | ||
471 | if (timer_pending(&t->proto_unreach_timer) && | 471 | if (del_timer(&t->proto_unreach_timer)) |
472 | del_timer(&t->proto_unreach_timer)) | ||
473 | sctp_association_put(asoc); | 472 | sctp_association_put(asoc); |
474 | 473 | ||
475 | sctp_do_sm(net, SCTP_EVENT_T_OTHER, | 474 | sctp_do_sm(net, SCTP_EVENT_T_OTHER, |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index f3f0f4dc31dd..391a245d5203 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -326,9 +326,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
326 | */ | 326 | */ |
327 | rcu_read_lock(); | 327 | rcu_read_lock(); |
328 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { | 328 | list_for_each_entry_rcu(laddr, &bp->address_list, list) { |
329 | if (!laddr->valid && laddr->state != SCTP_ADDR_SRC) | 329 | if (!laddr->valid) |
330 | continue; | 330 | continue; |
331 | if ((laddr->a.sa.sa_family == AF_INET6) && | 331 | if ((laddr->state == SCTP_ADDR_SRC) && |
332 | (laddr->a.sa.sa_family == AF_INET6) && | ||
332 | (scope <= sctp_scope(&laddr->a))) { | 333 | (scope <= sctp_scope(&laddr->a))) { |
333 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | 334 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); |
334 | if (!baddr || (matchlen < bmatchlen)) { | 335 | if (!baddr || (matchlen < bmatchlen)) { |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 9bcdbd02d777..01dca753db16 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -1700,10 +1700,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1700 | * address. | 1700 | * address. |
1701 | */ | 1701 | */ |
1702 | if (!transport->flight_size) { | 1702 | if (!transport->flight_size) { |
1703 | if (timer_pending(&transport->T3_rtx_timer) && | 1703 | if (del_timer(&transport->T3_rtx_timer)) |
1704 | del_timer(&transport->T3_rtx_timer)) { | ||
1705 | sctp_transport_put(transport); | 1704 | sctp_transport_put(transport); |
1706 | } | ||
1707 | } else if (restart_timer) { | 1705 | } else if (restart_timer) { |
1708 | if (!mod_timer(&transport->T3_rtx_timer, | 1706 | if (!mod_timer(&transport->T3_rtx_timer, |
1709 | jiffies + transport->rto)) | 1707 | jiffies + transport->rto)) |
diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 5f7518de2fd1..ad0dba870341 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c | |||
@@ -122,12 +122,12 @@ static const struct file_operations sctpprobe_fops = { | |||
122 | .llseek = noop_llseek, | 122 | .llseek = noop_llseek, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | sctp_disposition_t jsctp_sf_eat_sack(struct net *net, | 125 | static sctp_disposition_t jsctp_sf_eat_sack(struct net *net, |
126 | const struct sctp_endpoint *ep, | 126 | const struct sctp_endpoint *ep, |
127 | const struct sctp_association *asoc, | 127 | const struct sctp_association *asoc, |
128 | const sctp_subtype_t type, | 128 | const sctp_subtype_t type, |
129 | void *arg, | 129 | void *arg, |
130 | sctp_cmd_seq_t *commands) | 130 | sctp_cmd_seq_t *commands) |
131 | { | 131 | { |
132 | struct sctp_transport *sp; | 132 | struct sctp_transport *sp; |
133 | static __u32 lcwnd = 0; | 133 | static __u32 lcwnd = 0; |
@@ -183,13 +183,20 @@ static __init int sctpprobe_init(void) | |||
183 | { | 183 | { |
184 | int ret = -ENOMEM; | 184 | int ret = -ENOMEM; |
185 | 185 | ||
186 | /* Warning: if the function signature of sctp_sf_eat_sack_6_2, | ||
187 | * has been changed, you also have to change the signature of | ||
188 | * jsctp_sf_eat_sack, otherwise you end up right here! | ||
189 | */ | ||
190 | BUILD_BUG_ON(__same_type(sctp_sf_eat_sack_6_2, | ||
191 | jsctp_sf_eat_sack) == 0); | ||
192 | |||
186 | init_waitqueue_head(&sctpw.wait); | 193 | init_waitqueue_head(&sctpw.wait); |
187 | spin_lock_init(&sctpw.lock); | 194 | spin_lock_init(&sctpw.lock); |
188 | if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) | 195 | if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) |
189 | return ret; | 196 | return ret; |
190 | 197 | ||
191 | if (!proc_net_fops_create(&init_net, procname, S_IRUSR, | 198 | if (!proc_create(procname, S_IRUSR, init_net.proc_net, |
192 | &sctpprobe_fops)) | 199 | &sctpprobe_fops)) |
193 | goto free_kfifo; | 200 | goto free_kfifo; |
194 | 201 | ||
195 | ret = register_jprobe(&sctp_recv_probe); | 202 | ret = register_jprobe(&sctp_recv_probe); |
@@ -201,7 +208,7 @@ static __init int sctpprobe_init(void) | |||
201 | return 0; | 208 | return 0; |
202 | 209 | ||
203 | remove_proc: | 210 | remove_proc: |
204 | proc_net_remove(&init_net, procname); | 211 | remove_proc_entry(procname, init_net.proc_net); |
205 | free_kfifo: | 212 | free_kfifo: |
206 | kfifo_free(&sctpw.fifo); | 213 | kfifo_free(&sctpw.fifo); |
207 | return ret; | 214 | return ret; |
@@ -210,7 +217,7 @@ free_kfifo: | |||
210 | static __exit void sctpprobe_exit(void) | 217 | static __exit void sctpprobe_exit(void) |
211 | { | 218 | { |
212 | kfifo_free(&sctpw.fifo); | 219 | kfifo_free(&sctpw.fifo); |
213 | proc_net_remove(&init_net, procname); | 220 | remove_proc_entry(procname, init_net.proc_net); |
214 | unregister_jprobe(&sctp_recv_probe); | 221 | unregister_jprobe(&sctp_recv_probe); |
215 | } | 222 | } |
216 | 223 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index f898b1c58bd2..1c2e46cb9191 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -595,7 +595,7 @@ static void sctp_v4_ecn_capable(struct sock *sk) | |||
595 | INET_ECN_xmit(sk); | 595 | INET_ECN_xmit(sk); |
596 | } | 596 | } |
597 | 597 | ||
598 | void sctp_addr_wq_timeout_handler(unsigned long arg) | 598 | static void sctp_addr_wq_timeout_handler(unsigned long arg) |
599 | { | 599 | { |
600 | struct net *net = (struct net *)arg; | 600 | struct net *net = (struct net *)arg; |
601 | struct sctp_sockaddr_entry *addrw, *temp; | 601 | struct sctp_sockaddr_entry *addrw, *temp; |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 04df5301df04..cf579e71cff0 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -1589,8 +1589,6 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1589 | struct sctp_signed_cookie *cookie; | 1589 | struct sctp_signed_cookie *cookie; |
1590 | struct scatterlist sg; | 1590 | struct scatterlist sg; |
1591 | int headersize, bodysize; | 1591 | int headersize, bodysize; |
1592 | unsigned int keylen; | ||
1593 | char *key; | ||
1594 | 1592 | ||
1595 | /* Header size is static data prior to the actual cookie, including | 1593 | /* Header size is static data prior to the actual cookie, including |
1596 | * any padding. | 1594 | * any padding. |
@@ -1650,12 +1648,11 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
1650 | 1648 | ||
1651 | /* Sign the message. */ | 1649 | /* Sign the message. */ |
1652 | sg_init_one(&sg, &cookie->c, bodysize); | 1650 | sg_init_one(&sg, &cookie->c, bodysize); |
1653 | keylen = SCTP_SECRET_SIZE; | ||
1654 | key = (char *)ep->secret_key[ep->current_key]; | ||
1655 | desc.tfm = sctp_sk(ep->base.sk)->hmac; | 1651 | desc.tfm = sctp_sk(ep->base.sk)->hmac; |
1656 | desc.flags = 0; | 1652 | desc.flags = 0; |
1657 | 1653 | ||
1658 | if (crypto_hash_setkey(desc.tfm, key, keylen) || | 1654 | if (crypto_hash_setkey(desc.tfm, ep->secret_key, |
1655 | sizeof(ep->secret_key)) || | ||
1659 | crypto_hash_digest(&desc, &sg, bodysize, cookie->signature)) | 1656 | crypto_hash_digest(&desc, &sg, bodysize, cookie->signature)) |
1660 | goto free_cookie; | 1657 | goto free_cookie; |
1661 | } | 1658 | } |
@@ -1682,8 +1679,7 @@ struct sctp_association *sctp_unpack_cookie( | |||
1682 | int headersize, bodysize, fixed_size; | 1679 | int headersize, bodysize, fixed_size; |
1683 | __u8 *digest = ep->digest; | 1680 | __u8 *digest = ep->digest; |
1684 | struct scatterlist sg; | 1681 | struct scatterlist sg; |
1685 | unsigned int keylen, len; | 1682 | unsigned int len; |
1686 | char *key; | ||
1687 | sctp_scope_t scope; | 1683 | sctp_scope_t scope; |
1688 | struct sk_buff *skb = chunk->skb; | 1684 | struct sk_buff *skb = chunk->skb; |
1689 | struct timeval tv; | 1685 | struct timeval tv; |
@@ -1718,34 +1714,21 @@ struct sctp_association *sctp_unpack_cookie( | |||
1718 | goto no_hmac; | 1714 | goto no_hmac; |
1719 | 1715 | ||
1720 | /* Check the signature. */ | 1716 | /* Check the signature. */ |
1721 | keylen = SCTP_SECRET_SIZE; | ||
1722 | sg_init_one(&sg, bear_cookie, bodysize); | 1717 | sg_init_one(&sg, bear_cookie, bodysize); |
1723 | key = (char *)ep->secret_key[ep->current_key]; | ||
1724 | desc.tfm = sctp_sk(ep->base.sk)->hmac; | 1718 | desc.tfm = sctp_sk(ep->base.sk)->hmac; |
1725 | desc.flags = 0; | 1719 | desc.flags = 0; |
1726 | 1720 | ||
1727 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); | 1721 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); |
1728 | if (crypto_hash_setkey(desc.tfm, key, keylen) || | 1722 | if (crypto_hash_setkey(desc.tfm, ep->secret_key, |
1723 | sizeof(ep->secret_key)) || | ||
1729 | crypto_hash_digest(&desc, &sg, bodysize, digest)) { | 1724 | crypto_hash_digest(&desc, &sg, bodysize, digest)) { |
1730 | *error = -SCTP_IERROR_NOMEM; | 1725 | *error = -SCTP_IERROR_NOMEM; |
1731 | goto fail; | 1726 | goto fail; |
1732 | } | 1727 | } |
1733 | 1728 | ||
1734 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { | 1729 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { |
1735 | /* Try the previous key. */ | 1730 | *error = -SCTP_IERROR_BAD_SIG; |
1736 | key = (char *)ep->secret_key[ep->last_key]; | 1731 | goto fail; |
1737 | memset(digest, 0x00, SCTP_SIGNATURE_SIZE); | ||
1738 | if (crypto_hash_setkey(desc.tfm, key, keylen) || | ||
1739 | crypto_hash_digest(&desc, &sg, bodysize, digest)) { | ||
1740 | *error = -SCTP_IERROR_NOMEM; | ||
1741 | goto fail; | ||
1742 | } | ||
1743 | |||
1744 | if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) { | ||
1745 | /* Yikes! Still bad signature! */ | ||
1746 | *error = -SCTP_IERROR_BAD_SIG; | ||
1747 | goto fail; | ||
1748 | } | ||
1749 | } | 1732 | } |
1750 | 1733 | ||
1751 | no_hmac: | 1734 | no_hmac: |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index c9577754a708..8aab894aeabe 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -674,10 +674,8 @@ static void sctp_cmd_t3_rtx_timers_stop(sctp_cmd_seq_t *cmds, | |||
674 | 674 | ||
675 | list_for_each_entry(t, &asoc->peer.transport_addr_list, | 675 | list_for_each_entry(t, &asoc->peer.transport_addr_list, |
676 | transports) { | 676 | transports) { |
677 | if (timer_pending(&t->T3_rtx_timer) && | 677 | if (del_timer(&t->T3_rtx_timer)) |
678 | del_timer(&t->T3_rtx_timer)) { | ||
679 | sctp_transport_put(t); | 678 | sctp_transport_put(t); |
680 | } | ||
681 | } | 679 | } |
682 | } | 680 | } |
683 | 681 | ||
@@ -1517,7 +1515,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1517 | 1515 | ||
1518 | case SCTP_CMD_TIMER_STOP: | 1516 | case SCTP_CMD_TIMER_STOP: |
1519 | timer = &asoc->timers[cmd->obj.to]; | 1517 | timer = &asoc->timers[cmd->obj.to]; |
1520 | if (timer_pending(timer) && del_timer(timer)) | 1518 | if (del_timer(timer)) |
1521 | sctp_association_put(asoc); | 1519 | sctp_association_put(asoc); |
1522 | break; | 1520 | break; |
1523 | 1521 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9e65758cb038..cedd9bf67b8c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3390,7 +3390,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3390 | 3390 | ||
3391 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); | 3391 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); |
3392 | out: | 3392 | out: |
3393 | kfree(authkey); | 3393 | kzfree(authkey); |
3394 | return ret; | 3394 | return ret; |
3395 | } | 3395 | } |
3396 | 3396 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 4e45bb68aef0..fafd2a461ba0 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -151,13 +151,11 @@ void sctp_transport_free(struct sctp_transport *transport) | |||
151 | * structure hang around in memory since we know | 151 | * structure hang around in memory since we know |
152 | * the tranport is going away. | 152 | * the tranport is going away. |
153 | */ | 153 | */ |
154 | if (timer_pending(&transport->T3_rtx_timer) && | 154 | if (del_timer(&transport->T3_rtx_timer)) |
155 | del_timer(&transport->T3_rtx_timer)) | ||
156 | sctp_transport_put(transport); | 155 | sctp_transport_put(transport); |
157 | 156 | ||
158 | /* Delete the ICMP proto unreachable timer if it's active. */ | 157 | /* Delete the ICMP proto unreachable timer if it's active. */ |
159 | if (timer_pending(&transport->proto_unreach_timer) && | 158 | if (del_timer(&transport->proto_unreach_timer)) |
160 | del_timer(&transport->proto_unreach_timer)) | ||
161 | sctp_association_put(transport->asoc); | 159 | sctp_association_put(transport->asoc); |
162 | 160 | ||
163 | sctp_transport_put(transport); | 161 | sctp_transport_put(transport); |
@@ -168,10 +166,6 @@ static void sctp_transport_destroy_rcu(struct rcu_head *head) | |||
168 | struct sctp_transport *transport; | 166 | struct sctp_transport *transport; |
169 | 167 | ||
170 | transport = container_of(head, struct sctp_transport, rcu); | 168 | transport = container_of(head, struct sctp_transport, rcu); |
171 | if (transport->asoc) | ||
172 | sctp_association_put(transport->asoc); | ||
173 | |||
174 | sctp_packet_free(&transport->packet); | ||
175 | 169 | ||
176 | dst_release(transport->dst); | 170 | dst_release(transport->dst); |
177 | kfree(transport); | 171 | kfree(transport); |
@@ -186,6 +180,11 @@ static void sctp_transport_destroy(struct sctp_transport *transport) | |||
186 | SCTP_ASSERT(transport->dead, "Transport is not dead", return); | 180 | SCTP_ASSERT(transport->dead, "Transport is not dead", return); |
187 | 181 | ||
188 | call_rcu(&transport->rcu, sctp_transport_destroy_rcu); | 182 | call_rcu(&transport->rcu, sctp_transport_destroy_rcu); |
183 | |||
184 | sctp_packet_free(&transport->packet); | ||
185 | |||
186 | if (transport->asoc) | ||
187 | sctp_association_put(transport->asoc); | ||
189 | } | 188 | } |
190 | 189 | ||
191 | /* Start T3_rtx timer if it is not already running and update the heartbeat | 190 | /* Start T3_rtx timer if it is not already running and update the heartbeat |
@@ -654,10 +653,9 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
654 | void sctp_transport_immediate_rtx(struct sctp_transport *t) | 653 | void sctp_transport_immediate_rtx(struct sctp_transport *t) |
655 | { | 654 | { |
656 | /* Stop pending T3_rtx_timer */ | 655 | /* Stop pending T3_rtx_timer */ |
657 | if (timer_pending(&t->T3_rtx_timer)) { | 656 | if (del_timer(&t->T3_rtx_timer)) |
658 | (void)del_timer(&t->T3_rtx_timer); | ||
659 | sctp_transport_put(t); | 657 | sctp_transport_put(t); |
660 | } | 658 | |
661 | sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX); | 659 | sctp_retransmit(&t->asoc->outqueue, t, SCTP_RTXR_T3_RTX); |
662 | if (!timer_pending(&t->T3_rtx_timer)) { | 660 | if (!timer_pending(&t->T3_rtx_timer)) { |
663 | if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto)) | 661 | if (!mod_timer(&t->T3_rtx_timer, jiffies + t->rto)) |