diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-14 10:56:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-14 10:56:24 -0400 |
commit | 533bb8a4d7388686243c37a414c4448ba3566f8a (patch) | |
tree | 506ef946871e4499862ecc8513f49b69389ae865 /net | |
parent | 4f3f8e94b7b079131f0faf641e8afd790a6537d1 (diff) | |
parent | 159d83363b629c91d020734207c1bc788b96af5a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (31 commits)
[BRIDGE]: Fix crash in __ip_route_output_key with bridge netfilter
[NETFILTER]: ipt_CLUSTERIP: fix race between clusterip_config_find_get and _entry_put
[IPV6] ADDRCONF: Don't generate temporary address for ip6-ip6 interface.
[IPV6] ADDRCONF: Ensure disabling multicast RS even if privacy extensions are disabled.
[IPV6]: Use appropriate sock tclass setting for routing lookup.
[IPV6]: IPv6 extension header structures need to be packed.
[IPV6]: Fix ipv6 address fetching in raw6_icmp_error().
[NET]: Return more appropriate error from eth_validate_addr().
[ISDN]: Do not validate ISDN net device address prior to interface-up
[NET]: Fix kernel-doc for skb_segment
[SOCK] sk_stamp: should be initialized to ktime_set(-1L, 0)
net: check for underlength tap writes
net: make struct tun_struct private to tun.c
[SCTP]: IPv4 vs IPv6 addresses mess in sctp_inet[6]addr_event.
[SCTP]: Fix compiler warning about const qualifiers
[SCTP]: Fix protocol violation when receiving an error lenght INIT-ACK
[SCTP]: Add check for hmac_algo parameter in sctp_verify_param()
[NET_SCHED] cls_u32: refcounting fix for u32_delete()
[DCCP]: Fix skb->cb conflicts with IP
[AX25]: Potential ax25_uid_assoc-s leaks on module unload.
...
Diffstat (limited to 'net')
-rw-r--r-- | net/ax25/ax25_uid.c | 2 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 3 | ||||
-rw-r--r-- | net/core/skbuff.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 2 | ||||
-rw-r--r-- | net/dccp/dccp.h | 6 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 1 | ||||
-rw-r--r-- | net/dccp/output.c | 1 | ||||
-rw-r--r-- | net/dccp/proto.c | 3 | ||||
-rw-r--r-- | net/ethernet/eth.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_CLUSTERIP.c | 4 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 19 | ||||
-rw-r--r-- | net/ipv6/raw.c | 6 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 12 | ||||
-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 |
21 files changed, 106 insertions, 33 deletions
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index 5f4eb73fb9d3..57aeba729bae 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c | |||
@@ -218,9 +218,11 @@ void __exit ax25_uid_free(void) | |||
218 | struct hlist_node *node; | 218 | struct hlist_node *node; |
219 | 219 | ||
220 | write_lock(&ax25_uid_lock); | 220 | write_lock(&ax25_uid_lock); |
221 | again: | ||
221 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { | 222 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
222 | hlist_del_init(&ax25_uid->uid_node); | 223 | hlist_del_init(&ax25_uid->uid_node); |
223 | ax25_uid_put(ax25_uid); | 224 | ax25_uid_put(ax25_uid); |
225 | goto again; | ||
224 | } | 226 | } |
225 | write_unlock(&ax25_uid_lock); | 227 | write_unlock(&ax25_uid_lock); |
226 | } | 228 | } |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 1c0efd8ad9f3..af7e8be8d8d2 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -110,7 +110,8 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb) | |||
110 | * ipt_REJECT needs it. Future netfilter modules might | 110 | * ipt_REJECT needs it. Future netfilter modules might |
111 | * require us to fill additional fields. */ | 111 | * require us to fill additional fields. */ |
112 | static struct net_device __fake_net_device = { | 112 | static struct net_device __fake_net_device = { |
113 | .hard_header_len = ETH_HLEN | 113 | .hard_header_len = ETH_HLEN, |
114 | .nd_net = &init_net, | ||
114 | }; | 115 | }; |
115 | 116 | ||
116 | static struct rtable __fake_rtable = { | 117 | static struct rtable __fake_rtable = { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0d0fd28a9041..608701339620 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2131,8 +2131,8 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum); | |||
2131 | * @features: features for the output path (see dev->features) | 2131 | * @features: features for the output path (see dev->features) |
2132 | * | 2132 | * |
2133 | * This function performs segmentation on the given skb. It returns | 2133 | * This function performs segmentation on the given skb. It returns |
2134 | * the segment at the given position. It returns NULL if there are | 2134 | * a pointer to the first in a list of new skbs for the segments. |
2135 | * no more segments to generate, or when an error is encountered. | 2135 | * In case of error it returns ERR_PTR(err). |
2136 | */ | 2136 | */ |
2137 | struct sk_buff *skb_segment(struct sk_buff *skb, int features) | 2137 | struct sk_buff *skb_segment(struct sk_buff *skb, int features) |
2138 | { | 2138 | { |
diff --git a/net/core/sock.c b/net/core/sock.c index 2654c147c004..7a0567b4b2c9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1725,7 +1725,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1725 | sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; | 1725 | sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; |
1726 | sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; | 1726 | sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; |
1727 | 1727 | ||
1728 | sk->sk_stamp = ktime_set(-1L, -1L); | 1728 | sk->sk_stamp = ktime_set(-1L, 0); |
1729 | 1729 | ||
1730 | atomic_set(&sk->sk_refcnt, 1); | 1730 | atomic_set(&sk->sk_refcnt, 1); |
1731 | atomic_set(&sk->sk_drops, 0); | 1731 | atomic_set(&sk->sk_drops, 0); |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 287a62bc2e0f..ba2ef94a2302 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk, | |||
325 | * This is used for transmission as well as for reception. | 325 | * This is used for transmission as well as for reception. |
326 | */ | 326 | */ |
327 | struct dccp_skb_cb { | 327 | struct dccp_skb_cb { |
328 | union { | ||
329 | struct inet_skb_parm h4; | ||
330 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
331 | struct inet6_skb_parm h6; | ||
332 | #endif | ||
333 | } header; | ||
328 | __u8 dccpd_type:4; | 334 | __u8 dccpd_type:4; |
329 | __u8 dccpd_ccval:4; | 335 | __u8 dccpd_ccval:4; |
330 | __u8 dccpd_reset_code, | 336 | __u8 dccpd_reset_code, |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 474075adbde4..b33704415555 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, | |||
489 | 489 | ||
490 | dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr, | 490 | dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr, |
491 | ireq->rmt_addr); | 491 | ireq->rmt_addr); |
492 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | ||
493 | err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, | 492 | err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, |
494 | ireq->rmt_addr, | 493 | ireq->rmt_addr, |
495 | ireq->opt); | 494 | ireq->opt); |
diff --git a/net/dccp/output.c b/net/dccp/output.c index 3b763db3d863..3d7d628d870d 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
126 | 126 | ||
127 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); | 127 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
128 | 128 | ||
129 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | ||
130 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 129 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
131 | return net_xmit_eval(err); | 130 | return net_xmit_eval(err); |
132 | } | 131 | } |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index e3f5d37b84be..c91d3c1fd30d 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void) | |||
1057 | int ehash_order, bhash_order, i; | 1057 | int ehash_order, bhash_order, i; |
1058 | int rc = -ENOBUFS; | 1058 | int rc = -ENOBUFS; |
1059 | 1059 | ||
1060 | BUILD_BUG_ON(sizeof(struct dccp_skb_cb) > | ||
1061 | FIELD_SIZEOF(struct sk_buff, cb)); | ||
1062 | |||
1060 | dccp_hashinfo.bind_bucket_cachep = | 1063 | dccp_hashinfo.bind_bucket_cachep = |
1061 | kmem_cache_create("dccp_bind_bucket", | 1064 | kmem_cache_create("dccp_bind_bucket", |
1062 | sizeof(struct inet_bind_bucket), 0, | 1065 | sizeof(struct inet_bind_bucket), 0, |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index a7b417523e9b..a80839b02e3f 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -301,7 +301,7 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu) | |||
301 | static int eth_validate_addr(struct net_device *dev) | 301 | static int eth_validate_addr(struct net_device *dev) |
302 | { | 302 | { |
303 | if (!is_valid_ether_addr(dev->dev_addr)) | 303 | if (!is_valid_ether_addr(dev->dev_addr)) |
304 | return -EINVAL; | 304 | return -EADDRNOTAVAIL; |
305 | 305 | ||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 52926c8e3cc1..a12dd329e208 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -82,8 +82,8 @@ clusterip_config_put(struct clusterip_config *c) | |||
82 | static inline void | 82 | static inline void |
83 | clusterip_config_entry_put(struct clusterip_config *c) | 83 | clusterip_config_entry_put(struct clusterip_config *c) |
84 | { | 84 | { |
85 | write_lock_bh(&clusterip_lock); | ||
85 | if (atomic_dec_and_test(&c->entries)) { | 86 | if (atomic_dec_and_test(&c->entries)) { |
86 | write_lock_bh(&clusterip_lock); | ||
87 | list_del(&c->list); | 87 | list_del(&c->list); |
88 | write_unlock_bh(&clusterip_lock); | 88 | write_unlock_bh(&clusterip_lock); |
89 | 89 | ||
@@ -96,7 +96,9 @@ clusterip_config_entry_put(struct clusterip_config *c) | |||
96 | #ifdef CONFIG_PROC_FS | 96 | #ifdef CONFIG_PROC_FS |
97 | remove_proc_entry(c->pde->name, c->pde->parent); | 97 | remove_proc_entry(c->pde->name, c->pde->parent); |
98 | #endif | 98 | #endif |
99 | return; | ||
99 | } | 100 | } |
101 | write_unlock_bh(&clusterip_lock); | ||
100 | } | 102 | } |
101 | 103 | ||
102 | static struct clusterip_config * | 104 | static struct clusterip_config * |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a65935a9afd9..e08955baedff 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -371,25 +371,26 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
371 | */ | 371 | */ |
372 | in6_dev_hold(ndev); | 372 | in6_dev_hold(ndev); |
373 | 373 | ||
374 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | ||
375 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { | ||
376 | printk(KERN_INFO | ||
377 | "%s: Disabled Multicast RS\n", | ||
378 | dev->name); | ||
379 | ndev->cnf.rtr_solicits = 0; | ||
380 | } | ||
381 | #endif | ||
382 | |||
374 | #ifdef CONFIG_IPV6_PRIVACY | 383 | #ifdef CONFIG_IPV6_PRIVACY |
375 | setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); | 384 | setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); |
376 | if ((dev->flags&IFF_LOOPBACK) || | 385 | if ((dev->flags&IFF_LOOPBACK) || |
377 | dev->type == ARPHRD_TUNNEL || | 386 | dev->type == ARPHRD_TUNNEL || |
378 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 387 | dev->type == ARPHRD_TUNNEL6 || |
379 | dev->type == ARPHRD_SIT || | 388 | dev->type == ARPHRD_SIT || |
380 | #endif | ||
381 | dev->type == ARPHRD_NONE) { | 389 | dev->type == ARPHRD_NONE) { |
382 | printk(KERN_INFO | 390 | printk(KERN_INFO |
383 | "%s: Disabled Privacy Extensions\n", | 391 | "%s: Disabled Privacy Extensions\n", |
384 | dev->name); | 392 | dev->name); |
385 | ndev->cnf.use_tempaddr = -1; | 393 | ndev->cnf.use_tempaddr = -1; |
386 | |||
387 | if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) { | ||
388 | printk(KERN_INFO | ||
389 | "%s: Disabled Multicast RS\n", | ||
390 | dev->name); | ||
391 | ndev->cnf.rtr_solicits = 0; | ||
392 | } | ||
393 | } else { | 394 | } else { |
394 | in6_dev_hold(ndev); | 395 | in6_dev_hold(ndev); |
395 | ipv6_regen_rndid((unsigned long) ndev); | 396 | ipv6_regen_rndid((unsigned long) ndev); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 8897ccf8086a..0a6fbc1d1a50 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -372,8 +372,10 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, | |||
372 | read_lock(&raw_v6_hashinfo.lock); | 372 | read_lock(&raw_v6_hashinfo.lock); |
373 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); | 373 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); |
374 | if (sk != NULL) { | 374 | if (sk != NULL) { |
375 | saddr = &ipv6_hdr(skb)->saddr; | 375 | struct ipv6hdr *hdr = (struct ipv6hdr *) skb->data; |
376 | daddr = &ipv6_hdr(skb)->daddr; | 376 | |
377 | saddr = &hdr->saddr; | ||
378 | daddr = &hdr->daddr; | ||
377 | net = skb->dev->nd_net; | 379 | net = skb->dev->nd_net; |
378 | 380 | ||
379 | while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, | 381 | while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index c5c16b4b6e98..4d755444c449 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -411,8 +411,10 @@ static void u32_destroy(struct tcf_proto *tp) | |||
411 | } | 411 | } |
412 | } | 412 | } |
413 | 413 | ||
414 | for (ht=tp_c->hlist; ht; ht = ht->next) | 414 | for (ht = tp_c->hlist; ht; ht = ht->next) { |
415 | ht->refcnt--; | ||
415 | u32_clear_hnode(tp, ht); | 416 | u32_clear_hnode(tp, ht); |
417 | } | ||
416 | 418 | ||
417 | while ((ht = tp_c->hlist) != NULL) { | 419 | while ((ht = tp_c->hlist) != NULL) { |
418 | tp_c->hlist = ht->next; | 420 | tp_c->hlist = ht->next; |
@@ -441,8 +443,12 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg) | |||
441 | if (tp->root == ht) | 443 | if (tp->root == ht) |
442 | return -EINVAL; | 444 | return -EINVAL; |
443 | 445 | ||
444 | if (--ht->refcnt == 0) | 446 | if (ht->refcnt == 1) { |
447 | ht->refcnt--; | ||
445 | u32_destroy_hnode(tp, ht); | 448 | u32_destroy_hnode(tp, ht); |
449 | } else { | ||
450 | return -EBUSY; | ||
451 | } | ||
446 | 452 | ||
447 | return 0; | 453 | return 0; |
448 | } | 454 | } |
@@ -568,7 +574,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
568 | if (ht == NULL) | 574 | if (ht == NULL) |
569 | return -ENOBUFS; | 575 | return -ENOBUFS; |
570 | ht->tp_c = tp_c; | 576 | ht->tp_c = tp_c; |
571 | ht->refcnt = 0; | 577 | ht->refcnt = 1; |
572 | ht->divisor = divisor; | 578 | ht->divisor = divisor; |
573 | ht->handle = handle; | 579 | ht->handle = handle; |
574 | ht->prio = tp->prio; | 580 | ht->prio = tp->prio; |
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; | ||
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 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 | } |