diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ieee80211/ieee80211_rx.c | 6 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 2 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 54 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 18 | ||||
-rw-r--r-- | net/mac80211/ieee80211.c | 2 | ||||
-rw-r--r-- | net/mac80211/rc80211_simple.c | 2 | ||||
-rw-r--r-- | net/mac80211/wme.c | 2 | ||||
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 13 | ||||
-rw-r--r-- | net/sched/sch_sfq.c | 53 | ||||
-rw-r--r-- | net/sctp/bind_addr.c | 2 | ||||
-rw-r--r-- | net/sctp/input.c | 8 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 8 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 46 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 243 | ||||
-rw-r--r-- | net/sctp/sm_statetable.c | 16 | ||||
-rw-r--r-- | net/socket.c | 3 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 3 | ||||
-rw-r--r-- | net/wireless/core.c | 2 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 2 |
20 files changed, 368 insertions, 136 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index f2de2e48b021..6284c99b456e 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -366,6 +366,12 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
366 | frag = WLAN_GET_SEQ_FRAG(sc); | 366 | frag = WLAN_GET_SEQ_FRAG(sc); |
367 | hdrlen = ieee80211_get_hdrlen(fc); | 367 | hdrlen = ieee80211_get_hdrlen(fc); |
368 | 368 | ||
369 | if (skb->len < hdrlen) { | ||
370 | printk(KERN_INFO "%s: invalid SKB length %d\n", | ||
371 | dev->name, skb->len); | ||
372 | goto rx_dropped; | ||
373 | } | ||
374 | |||
369 | /* Put this code here so that we avoid duplicating it in all | 375 | /* Put this code here so that we avoid duplicating it in all |
370 | * Rx paths. - Jean II */ | 376 | * Rx paths. - Jean II */ |
371 | #ifdef CONFIG_WIRELESS_EXT | 377 | #ifdef CONFIG_WIRELESS_EXT |
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index afb6c6698b27..e475f2e1be13 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -273,8 +273,6 @@ ieee80211softmac_assoc_work(struct work_struct *work) | |||
273 | ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); | 273 | ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); |
274 | if (ieee80211softmac_start_scan(mac)) { | 274 | if (ieee80211softmac_start_scan(mac)) { |
275 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); | 275 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); |
276 | mac->associnfo.associating = 0; | ||
277 | mac->associnfo.associated = 0; | ||
278 | } | 276 | } |
279 | goto out; | 277 | goto out; |
280 | } else { | 278 | } else { |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index d054e9224b3e..442b9875f3fb 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -70,44 +70,30 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
70 | char *extra) | 70 | char *extra) |
71 | { | 71 | { |
72 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | 72 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); |
73 | struct ieee80211softmac_network *n; | ||
74 | struct ieee80211softmac_auth_queue_item *authptr; | 73 | struct ieee80211softmac_auth_queue_item *authptr; |
75 | int length = 0; | 74 | int length = 0; |
76 | 75 | ||
77 | check_assoc_again: | 76 | check_assoc_again: |
78 | mutex_lock(&sm->associnfo.mutex); | 77 | mutex_lock(&sm->associnfo.mutex); |
79 | /* Check if we're already associating to this or another network | ||
80 | * If it's another network, cancel and start over with our new network | ||
81 | * If it's our network, ignore the change, we're already doing it! | ||
82 | */ | ||
83 | if((sm->associnfo.associating || sm->associnfo.associated) && | 78 | if((sm->associnfo.associating || sm->associnfo.associated) && |
84 | (data->essid.flags && data->essid.length)) { | 79 | (data->essid.flags && data->essid.length)) { |
85 | /* Get the associating network */ | 80 | dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); |
86 | n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); | 81 | /* Cancel assoc work */ |
87 | if(n && n->essid.len == data->essid.length && | 82 | cancel_delayed_work(&sm->associnfo.work); |
88 | !memcmp(n->essid.data, extra, n->essid.len)) { | 83 | /* We don't have to do this, but it's a little cleaner */ |
89 | dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", | 84 | list_for_each_entry(authptr, &sm->auth_queue, list) |
90 | MAC_ARG(sm->associnfo.bssid)); | 85 | cancel_delayed_work(&authptr->work); |
91 | goto out; | 86 | sm->associnfo.bssvalid = 0; |
92 | } else { | 87 | sm->associnfo.bssfixed = 0; |
93 | dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); | 88 | sm->associnfo.associating = 0; |
94 | /* Cancel assoc work */ | 89 | sm->associnfo.associated = 0; |
95 | cancel_delayed_work(&sm->associnfo.work); | 90 | /* We must unlock to avoid deadlocks with the assoc workqueue |
96 | /* We don't have to do this, but it's a little cleaner */ | 91 | * on the associnfo.mutex */ |
97 | list_for_each_entry(authptr, &sm->auth_queue, list) | 92 | mutex_unlock(&sm->associnfo.mutex); |
98 | cancel_delayed_work(&authptr->work); | 93 | flush_scheduled_work(); |
99 | sm->associnfo.bssvalid = 0; | 94 | /* Avoid race! Check assoc status again. Maybe someone started an |
100 | sm->associnfo.bssfixed = 0; | 95 | * association while we flushed. */ |
101 | sm->associnfo.associating = 0; | 96 | goto check_assoc_again; |
102 | sm->associnfo.associated = 0; | ||
103 | /* We must unlock to avoid deadlocks with the assoc workqueue | ||
104 | * on the associnfo.mutex */ | ||
105 | mutex_unlock(&sm->associnfo.mutex); | ||
106 | flush_scheduled_work(); | ||
107 | /* Avoid race! Check assoc status again. Maybe someone started an | ||
108 | * association while we flushed. */ | ||
109 | goto check_assoc_again; | ||
110 | } | ||
111 | } | 97 | } |
112 | 98 | ||
113 | sm->associnfo.static_essid = 0; | 99 | sm->associnfo.static_essid = 0; |
@@ -153,13 +139,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev, | |||
153 | data->essid.length = sm->associnfo.req_essid.len; | 139 | data->essid.length = sm->associnfo.req_essid.len; |
154 | data->essid.flags = 1; /* active */ | 140 | data->essid.flags = 1; /* active */ |
155 | memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len); | 141 | memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len); |
156 | } | 142 | dprintk(KERN_INFO PFX "Getting essid from req_essid\n"); |
157 | 143 | } else if (sm->associnfo.associated || sm->associnfo.associating) { | |
158 | /* If we're associating/associated, return that */ | 144 | /* If we're associating/associated, return that */ |
159 | if (sm->associnfo.associated || sm->associnfo.associating) { | ||
160 | data->essid.length = sm->associnfo.associate_essid.len; | 145 | data->essid.length = sm->associnfo.associate_essid.len; |
161 | data->essid.flags = 1; /* active */ | 146 | data->essid.flags = 1; /* active */ |
162 | memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); | 147 | memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); |
148 | dprintk(KERN_INFO PFX "Getting essid from associate_essid\n"); | ||
163 | } | 149 | } |
164 | mutex_unlock(&sm->associnfo.mutex); | 150 | mutex_unlock(&sm->associnfo.mutex); |
165 | 151 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c94627c8c7e..e089a978e128 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -833,8 +833,7 @@ static struct tcp_md5sig_key * | |||
833 | return NULL; | 833 | return NULL; |
834 | for (i = 0; i < tp->md5sig_info->entries4; i++) { | 834 | for (i = 0; i < tp->md5sig_info->entries4; i++) { |
835 | if (tp->md5sig_info->keys4[i].addr == addr) | 835 | if (tp->md5sig_info->keys4[i].addr == addr) |
836 | return (struct tcp_md5sig_key *) | 836 | return &tp->md5sig_info->keys4[i].base; |
837 | &tp->md5sig_info->keys4[i]; | ||
838 | } | 837 | } |
839 | return NULL; | 838 | return NULL; |
840 | } | 839 | } |
@@ -865,9 +864,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, | |||
865 | key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); | 864 | key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr); |
866 | if (key) { | 865 | if (key) { |
867 | /* Pre-existing entry - just update that one. */ | 866 | /* Pre-existing entry - just update that one. */ |
868 | kfree(key->key); | 867 | kfree(key->base.key); |
869 | key->key = newkey; | 868 | key->base.key = newkey; |
870 | key->keylen = newkeylen; | 869 | key->base.keylen = newkeylen; |
871 | } else { | 870 | } else { |
872 | struct tcp_md5sig_info *md5sig; | 871 | struct tcp_md5sig_info *md5sig; |
873 | 872 | ||
@@ -906,9 +905,9 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, | |||
906 | md5sig->alloced4++; | 905 | md5sig->alloced4++; |
907 | } | 906 | } |
908 | md5sig->entries4++; | 907 | md5sig->entries4++; |
909 | md5sig->keys4[md5sig->entries4 - 1].addr = addr; | 908 | md5sig->keys4[md5sig->entries4 - 1].addr = addr; |
910 | md5sig->keys4[md5sig->entries4 - 1].key = newkey; | 909 | md5sig->keys4[md5sig->entries4 - 1].base.key = newkey; |
911 | md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen; | 910 | md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen; |
912 | } | 911 | } |
913 | return 0; | 912 | return 0; |
914 | } | 913 | } |
@@ -930,7 +929,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr) | |||
930 | for (i = 0; i < tp->md5sig_info->entries4; i++) { | 929 | for (i = 0; i < tp->md5sig_info->entries4; i++) { |
931 | if (tp->md5sig_info->keys4[i].addr == addr) { | 930 | if (tp->md5sig_info->keys4[i].addr == addr) { |
932 | /* Free the key */ | 931 | /* Free the key */ |
933 | kfree(tp->md5sig_info->keys4[i].key); | 932 | kfree(tp->md5sig_info->keys4[i].base.key); |
934 | tp->md5sig_info->entries4--; | 933 | tp->md5sig_info->entries4--; |
935 | 934 | ||
936 | if (tp->md5sig_info->entries4 == 0) { | 935 | if (tp->md5sig_info->entries4 == 0) { |
@@ -964,7 +963,7 @@ static void tcp_v4_clear_md5_list(struct sock *sk) | |||
964 | if (tp->md5sig_info->entries4) { | 963 | if (tp->md5sig_info->entries4) { |
965 | int i; | 964 | int i; |
966 | for (i = 0; i < tp->md5sig_info->entries4; i++) | 965 | for (i = 0; i < tp->md5sig_info->entries4; i++) |
967 | kfree(tp->md5sig_info->keys4[i].key); | 966 | kfree(tp->md5sig_info->keys4[i].base.key); |
968 | tp->md5sig_info->entries4 = 0; | 967 | tp->md5sig_info->entries4 = 0; |
969 | tcp_free_md5sig_pool(); | 968 | tcp_free_md5sig_pool(); |
970 | } | 969 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 0f7defb482e9..3e06799b37a6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -539,7 +539,7 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, | |||
539 | 539 | ||
540 | for (i = 0; i < tp->md5sig_info->entries6; i++) { | 540 | for (i = 0; i < tp->md5sig_info->entries6; i++) { |
541 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) | 541 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) |
542 | return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i]; | 542 | return &tp->md5sig_info->keys6[i].base; |
543 | } | 543 | } |
544 | return NULL; | 544 | return NULL; |
545 | } | 545 | } |
@@ -567,9 +567,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, | |||
567 | key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); | 567 | key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer); |
568 | if (key) { | 568 | if (key) { |
569 | /* modify existing entry - just update that one */ | 569 | /* modify existing entry - just update that one */ |
570 | kfree(key->key); | 570 | kfree(key->base.key); |
571 | key->key = newkey; | 571 | key->base.key = newkey; |
572 | key->keylen = newkeylen; | 572 | key->base.keylen = newkeylen; |
573 | } else { | 573 | } else { |
574 | /* reallocate new list if current one is full. */ | 574 | /* reallocate new list if current one is full. */ |
575 | if (!tp->md5sig_info) { | 575 | if (!tp->md5sig_info) { |
@@ -603,8 +603,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, | |||
603 | 603 | ||
604 | ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, | 604 | ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr, |
605 | peer); | 605 | peer); |
606 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey; | 606 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey; |
607 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen; | 607 | tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen; |
608 | 608 | ||
609 | tp->md5sig_info->entries6++; | 609 | tp->md5sig_info->entries6++; |
610 | } | 610 | } |
@@ -626,7 +626,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) | |||
626 | for (i = 0; i < tp->md5sig_info->entries6; i++) { | 626 | for (i = 0; i < tp->md5sig_info->entries6; i++) { |
627 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { | 627 | if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { |
628 | /* Free the key */ | 628 | /* Free the key */ |
629 | kfree(tp->md5sig_info->keys6[i].key); | 629 | kfree(tp->md5sig_info->keys6[i].base.key); |
630 | tp->md5sig_info->entries6--; | 630 | tp->md5sig_info->entries6--; |
631 | 631 | ||
632 | if (tp->md5sig_info->entries6 == 0) { | 632 | if (tp->md5sig_info->entries6 == 0) { |
@@ -657,7 +657,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk) | |||
657 | 657 | ||
658 | if (tp->md5sig_info->entries6) { | 658 | if (tp->md5sig_info->entries6) { |
659 | for (i = 0; i < tp->md5sig_info->entries6; i++) | 659 | for (i = 0; i < tp->md5sig_info->entries6; i++) |
660 | kfree(tp->md5sig_info->keys6[i].key); | 660 | kfree(tp->md5sig_info->keys6[i].base.key); |
661 | tp->md5sig_info->entries6 = 0; | 661 | tp->md5sig_info->entries6 = 0; |
662 | tcp_free_md5sig_pool(); | 662 | tcp_free_md5sig_pool(); |
663 | } | 663 | } |
@@ -668,7 +668,7 @@ static void tcp_v6_clear_md5_list (struct sock *sk) | |||
668 | 668 | ||
669 | if (tp->md5sig_info->entries4) { | 669 | if (tp->md5sig_info->entries4) { |
670 | for (i = 0; i < tp->md5sig_info->entries4; i++) | 670 | for (i = 0; i < tp->md5sig_info->entries4; i++) |
671 | kfree(tp->md5sig_info->keys4[i].key); | 671 | kfree(tp->md5sig_info->keys4[i].base.key); |
672 | tp->md5sig_info->entries4 = 0; | 672 | tp->md5sig_info->entries4 = 0; |
673 | tcp_free_md5sig_pool(); | 673 | tcp_free_md5sig_pool(); |
674 | } | 674 | } |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 7286c389a4d0..ff2172ffd861 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -5259,7 +5259,7 @@ static void __exit ieee80211_exit(void) | |||
5259 | } | 5259 | } |
5260 | 5260 | ||
5261 | 5261 | ||
5262 | module_init(ieee80211_init); | 5262 | subsys_initcall(ieee80211_init); |
5263 | module_exit(ieee80211_exit); | 5263 | module_exit(ieee80211_exit); |
5264 | 5264 | ||
5265 | MODULE_DESCRIPTION("IEEE 802.11 subsystem"); | 5265 | MODULE_DESCRIPTION("IEEE 802.11 subsystem"); |
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index f6780d63b342..17b9f46bbf2b 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c | |||
@@ -431,7 +431,7 @@ static void __exit rate_control_simple_exit(void) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | 433 | ||
434 | module_init(rate_control_simple_init); | 434 | subsys_initcall(rate_control_simple_init); |
435 | module_exit(rate_control_simple_exit); | 435 | module_exit(rate_control_simple_exit); |
436 | 436 | ||
437 | MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); | 437 | MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 89ce81529694..7ab82b376e1b 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -424,7 +424,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct rtattr *opt) | |||
424 | skb_queue_head_init(&q->requeued[i]); | 424 | skb_queue_head_init(&q->requeued[i]); |
425 | q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, | 425 | q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, |
426 | qd->handle); | 426 | qd->handle); |
427 | if (q->queues[i] == 0) { | 427 | if (!q->queues[i]) { |
428 | q->queues[i] = &noop_qdisc; | 428 | q->queues[i] = &noop_qdisc; |
429 | printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); | 429 | printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); |
430 | } | 430 | } |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e185a5b55913..2351533a8507 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -58,7 +58,6 @@ struct nfulnl_instance { | |||
58 | 58 | ||
59 | unsigned int qlen; /* number of nlmsgs in skb */ | 59 | unsigned int qlen; /* number of nlmsgs in skb */ |
60 | struct sk_buff *skb; /* pre-allocatd skb */ | 60 | struct sk_buff *skb; /* pre-allocatd skb */ |
61 | struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */ | ||
62 | struct timer_list timer; | 61 | struct timer_list timer; |
63 | int peer_pid; /* PID of the peer process */ | 62 | int peer_pid; /* PID of the peer process */ |
64 | 63 | ||
@@ -345,10 +344,12 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size, | |||
345 | static int | 344 | static int |
346 | __nfulnl_send(struct nfulnl_instance *inst) | 345 | __nfulnl_send(struct nfulnl_instance *inst) |
347 | { | 346 | { |
348 | int status; | 347 | int status = -1; |
349 | 348 | ||
350 | if (inst->qlen > 1) | 349 | if (inst->qlen > 1) |
351 | inst->lastnlh->nlmsg_type = NLMSG_DONE; | 350 | NLMSG_PUT(inst->skb, 0, 0, |
351 | NLMSG_DONE, | ||
352 | sizeof(struct nfgenmsg)); | ||
352 | 353 | ||
353 | status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT); | 354 | status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT); |
354 | if (status < 0) { | 355 | if (status < 0) { |
@@ -358,8 +359,8 @@ __nfulnl_send(struct nfulnl_instance *inst) | |||
358 | 359 | ||
359 | inst->qlen = 0; | 360 | inst->qlen = 0; |
360 | inst->skb = NULL; | 361 | inst->skb = NULL; |
361 | inst->lastnlh = NULL; | ||
362 | 362 | ||
363 | nlmsg_failure: | ||
363 | return status; | 364 | return status; |
364 | } | 365 | } |
365 | 366 | ||
@@ -538,7 +539,6 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
538 | } | 539 | } |
539 | 540 | ||
540 | nlh->nlmsg_len = inst->skb->tail - old_tail; | 541 | nlh->nlmsg_len = inst->skb->tail - old_tail; |
541 | inst->lastnlh = nlh; | ||
542 | return 0; | 542 | return 0; |
543 | 543 | ||
544 | nlmsg_failure: | 544 | nlmsg_failure: |
@@ -644,7 +644,8 @@ nfulnl_log_packet(unsigned int pf, | |||
644 | } | 644 | } |
645 | 645 | ||
646 | if (inst->qlen >= qthreshold || | 646 | if (inst->qlen >= qthreshold || |
647 | (inst->skb && size > skb_tailroom(inst->skb))) { | 647 | (inst->skb && size > |
648 | skb_tailroom(inst->skb) - sizeof(struct nfgenmsg))) { | ||
648 | /* either the queue len is too high or we don't have | 649 | /* either the queue len is too high or we don't have |
649 | * enough room in the skb left. flush to userspace. */ | 650 | * enough room in the skb left. flush to userspace. */ |
650 | UDEBUG("flushing old skb\n"); | 651 | UDEBUG("flushing old skb\n"); |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 957957309859..b542c875e154 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/ipv6.h> | 20 | #include <linux/ipv6.h> |
21 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
22 | #include <linux/jhash.h> | ||
22 | #include <net/ip.h> | 23 | #include <net/ip.h> |
23 | #include <net/netlink.h> | 24 | #include <net/netlink.h> |
24 | #include <net/pkt_sched.h> | 25 | #include <net/pkt_sched.h> |
@@ -95,7 +96,7 @@ struct sfq_sched_data | |||
95 | 96 | ||
96 | /* Variables */ | 97 | /* Variables */ |
97 | struct timer_list perturb_timer; | 98 | struct timer_list perturb_timer; |
98 | int perturbation; | 99 | u32 perturbation; |
99 | sfq_index tail; /* Index of current slot in round */ | 100 | sfq_index tail; /* Index of current slot in round */ |
100 | sfq_index max_depth; /* Maximal depth */ | 101 | sfq_index max_depth; /* Maximal depth */ |
101 | 102 | ||
@@ -109,12 +110,7 @@ struct sfq_sched_data | |||
109 | 110 | ||
110 | static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) | 111 | static __inline__ unsigned sfq_fold_hash(struct sfq_sched_data *q, u32 h, u32 h1) |
111 | { | 112 | { |
112 | int pert = q->perturbation; | 113 | return jhash_2words(h, h1, q->perturbation) & (SFQ_HASH_DIVISOR - 1); |
113 | |||
114 | /* Have we any rotation primitives? If not, WHY? */ | ||
115 | h ^= (h1<<pert) ^ (h1>>(0x1F - pert)); | ||
116 | h ^= h>>10; | ||
117 | return h & 0x3FF; | ||
118 | } | 114 | } |
119 | 115 | ||
120 | static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | 116 | static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) |
@@ -256,6 +252,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
256 | q->ht[hash] = x = q->dep[SFQ_DEPTH].next; | 252 | q->ht[hash] = x = q->dep[SFQ_DEPTH].next; |
257 | q->hash[x] = hash; | 253 | q->hash[x] = hash; |
258 | } | 254 | } |
255 | /* If selected queue has length q->limit, this means that | ||
256 | * all another queues are empty and that we do simple tail drop, | ||
257 | * i.e. drop _this_ packet. | ||
258 | */ | ||
259 | if (q->qs[x].qlen >= q->limit) | ||
260 | return qdisc_drop(skb, sch); | ||
261 | |||
259 | sch->qstats.backlog += skb->len; | 262 | sch->qstats.backlog += skb->len; |
260 | __skb_queue_tail(&q->qs[x], skb); | 263 | __skb_queue_tail(&q->qs[x], skb); |
261 | sfq_inc(q, x); | 264 | sfq_inc(q, x); |
@@ -270,7 +273,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
270 | q->tail = x; | 273 | q->tail = x; |
271 | } | 274 | } |
272 | } | 275 | } |
273 | if (++sch->q.qlen < q->limit-1) { | 276 | if (++sch->q.qlen <= q->limit) { |
274 | sch->bstats.bytes += skb->len; | 277 | sch->bstats.bytes += skb->len; |
275 | sch->bstats.packets++; | 278 | sch->bstats.packets++; |
276 | return 0; | 279 | return 0; |
@@ -294,6 +297,19 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) | |||
294 | } | 297 | } |
295 | sch->qstats.backlog += skb->len; | 298 | sch->qstats.backlog += skb->len; |
296 | __skb_queue_head(&q->qs[x], skb); | 299 | __skb_queue_head(&q->qs[x], skb); |
300 | /* If selected queue has length q->limit+1, this means that | ||
301 | * all another queues are empty and we do simple tail drop. | ||
302 | * This packet is still requeued at head of queue, tail packet | ||
303 | * is dropped. | ||
304 | */ | ||
305 | if (q->qs[x].qlen > q->limit) { | ||
306 | skb = q->qs[x].prev; | ||
307 | __skb_unlink(skb, &q->qs[x]); | ||
308 | sch->qstats.drops++; | ||
309 | sch->qstats.backlog -= skb->len; | ||
310 | kfree_skb(skb); | ||
311 | return NET_XMIT_CN; | ||
312 | } | ||
297 | sfq_inc(q, x); | 313 | sfq_inc(q, x); |
298 | if (q->qs[x].qlen == 1) { /* The flow is new */ | 314 | if (q->qs[x].qlen == 1) { /* The flow is new */ |
299 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ | 315 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ |
@@ -306,7 +322,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) | |||
306 | q->tail = x; | 322 | q->tail = x; |
307 | } | 323 | } |
308 | } | 324 | } |
309 | if (++sch->q.qlen < q->limit - 1) { | 325 | if (++sch->q.qlen <= q->limit) { |
310 | sch->qstats.requeues++; | 326 | sch->qstats.requeues++; |
311 | return 0; | 327 | return 0; |
312 | } | 328 | } |
@@ -370,12 +386,10 @@ static void sfq_perturbation(unsigned long arg) | |||
370 | struct Qdisc *sch = (struct Qdisc*)arg; | 386 | struct Qdisc *sch = (struct Qdisc*)arg; |
371 | struct sfq_sched_data *q = qdisc_priv(sch); | 387 | struct sfq_sched_data *q = qdisc_priv(sch); |
372 | 388 | ||
373 | q->perturbation = net_random()&0x1F; | 389 | get_random_bytes(&q->perturbation, 4); |
374 | 390 | ||
375 | if (q->perturb_period) { | 391 | if (q->perturb_period) |
376 | q->perturb_timer.expires = jiffies + q->perturb_period; | 392 | mod_timer(&q->perturb_timer, jiffies + q->perturb_period); |
377 | add_timer(&q->perturb_timer); | ||
378 | } | ||
379 | } | 393 | } |
380 | 394 | ||
381 | static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | 395 | static int sfq_change(struct Qdisc *sch, struct rtattr *opt) |
@@ -391,17 +405,17 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); | 405 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); |
392 | q->perturb_period = ctl->perturb_period*HZ; | 406 | q->perturb_period = ctl->perturb_period*HZ; |
393 | if (ctl->limit) | 407 | if (ctl->limit) |
394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); | 408 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1); |
395 | 409 | ||
396 | qlen = sch->q.qlen; | 410 | qlen = sch->q.qlen; |
397 | while (sch->q.qlen >= q->limit-1) | 411 | while (sch->q.qlen > q->limit) |
398 | sfq_drop(sch); | 412 | sfq_drop(sch); |
399 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); | 413 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); |
400 | 414 | ||
401 | del_timer(&q->perturb_timer); | 415 | del_timer(&q->perturb_timer); |
402 | if (q->perturb_period) { | 416 | if (q->perturb_period) { |
403 | q->perturb_timer.expires = jiffies + q->perturb_period; | 417 | mod_timer(&q->perturb_timer, jiffies + q->perturb_period); |
404 | add_timer(&q->perturb_timer); | 418 | get_random_bytes(&q->perturbation, 4); |
405 | } | 419 | } |
406 | sch_tree_unlock(sch); | 420 | sch_tree_unlock(sch); |
407 | return 0; | 421 | return 0; |
@@ -423,12 +437,13 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) | |||
423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; | 437 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; |
424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; | 438 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; |
425 | } | 439 | } |
426 | q->limit = SFQ_DEPTH; | 440 | q->limit = SFQ_DEPTH - 1; |
427 | q->max_depth = 0; | 441 | q->max_depth = 0; |
428 | q->tail = SFQ_DEPTH; | 442 | q->tail = SFQ_DEPTH; |
429 | if (opt == NULL) { | 443 | if (opt == NULL) { |
430 | q->quantum = psched_mtu(sch->dev); | 444 | q->quantum = psched_mtu(sch->dev); |
431 | q->perturb_period = 0; | 445 | q->perturb_period = 0; |
446 | get_random_bytes(&q->perturbation, 4); | ||
432 | } else { | 447 | } else { |
433 | int err = sfq_change(sch, opt); | 448 | int err = sfq_change(sch, opt); |
434 | if (err) | 449 | if (err) |
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index d35cbf5aae33..dfffa94fb9f6 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
@@ -181,7 +181,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, | |||
181 | * structure. | 181 | * structure. |
182 | */ | 182 | */ |
183 | int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, | 183 | int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr, |
184 | void (*rcu_call)(struct rcu_head *head, | 184 | void fastcall (*rcu_call)(struct rcu_head *head, |
185 | void (*func)(struct rcu_head *head))) | 185 | void (*func)(struct rcu_head *head))) |
186 | { | 186 | { |
187 | struct sctp_sockaddr_entry *addr, *temp; | 187 | struct sctp_sockaddr_entry *addr, *temp; |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 47e56017f4ce..f9a0c9276e3b 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -622,6 +622,14 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
622 | if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type) | 622 | if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type) |
623 | goto discard; | 623 | goto discard; |
624 | 624 | ||
625 | /* RFC 4460, 2.11.2 | ||
626 | * This will discard packets with INIT chunk bundled as | ||
627 | * subsequent chunks in the packet. When INIT is first, | ||
628 | * the normal INIT processing will discard the chunk. | ||
629 | */ | ||
630 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) | ||
631 | goto discard; | ||
632 | |||
625 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | 633 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR |
626 | * or a COOKIE ACK the SCTP Packet should be silently | 634 | * or a COOKIE ACK the SCTP Packet should be silently |
627 | * discarded. | 635 | * discarded. |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 88aa22407549..e4ea7fdf36ed 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -130,6 +130,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | |||
130 | /* Force chunk->skb->data to chunk->chunk_end. */ | 130 | /* Force chunk->skb->data to chunk->chunk_end. */ |
131 | skb_pull(chunk->skb, | 131 | skb_pull(chunk->skb, |
132 | chunk->chunk_end - chunk->skb->data); | 132 | chunk->chunk_end - chunk->skb->data); |
133 | |||
134 | /* Verify that we have at least chunk headers | ||
135 | * worth of buffer left. | ||
136 | */ | ||
137 | if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) { | ||
138 | sctp_chunk_free(chunk); | ||
139 | chunk = queue->in_progress = NULL; | ||
140 | } | ||
133 | } | 141 | } |
134 | } | 142 | } |
135 | 143 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 2e34220d94cd..23ae37ec8711 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -2499,6 +2499,52 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, | |||
2499 | return SCTP_ERROR_NO_ERROR; | 2499 | return SCTP_ERROR_NO_ERROR; |
2500 | } | 2500 | } |
2501 | 2501 | ||
2502 | /* Verify the ASCONF packet before we process it. */ | ||
2503 | int sctp_verify_asconf(const struct sctp_association *asoc, | ||
2504 | struct sctp_paramhdr *param_hdr, void *chunk_end, | ||
2505 | struct sctp_paramhdr **errp) { | ||
2506 | sctp_addip_param_t *asconf_param; | ||
2507 | union sctp_params param; | ||
2508 | int length, plen; | ||
2509 | |||
2510 | param.v = (sctp_paramhdr_t *) param_hdr; | ||
2511 | while (param.v <= chunk_end - sizeof(sctp_paramhdr_t)) { | ||
2512 | length = ntohs(param.p->length); | ||
2513 | *errp = param.p; | ||
2514 | |||
2515 | if (param.v > chunk_end - length || | ||
2516 | length < sizeof(sctp_paramhdr_t)) | ||
2517 | return 0; | ||
2518 | |||
2519 | switch (param.p->type) { | ||
2520 | case SCTP_PARAM_ADD_IP: | ||
2521 | case SCTP_PARAM_DEL_IP: | ||
2522 | case SCTP_PARAM_SET_PRIMARY: | ||
2523 | asconf_param = (sctp_addip_param_t *)param.v; | ||
2524 | plen = ntohs(asconf_param->param_hdr.length); | ||
2525 | if (plen < sizeof(sctp_addip_param_t) + | ||
2526 | sizeof(sctp_paramhdr_t)) | ||
2527 | return 0; | ||
2528 | break; | ||
2529 | case SCTP_PARAM_SUCCESS_REPORT: | ||
2530 | case SCTP_PARAM_ADAPTATION_LAYER_IND: | ||
2531 | if (length != sizeof(sctp_addip_param_t)) | ||
2532 | return 0; | ||
2533 | |||
2534 | break; | ||
2535 | default: | ||
2536 | break; | ||
2537 | } | ||
2538 | |||
2539 | param.v += WORD_ROUND(length); | ||
2540 | } | ||
2541 | |||
2542 | if (param.v != chunk_end) | ||
2543 | return 0; | ||
2544 | |||
2545 | return 1; | ||
2546 | } | ||
2547 | |||
2502 | /* Process an incoming ASCONF chunk with the next expected serial no. and | 2548 | /* Process an incoming ASCONF chunk with the next expected serial no. and |
2503 | * return an ASCONF_ACK chunk to be sent in response. | 2549 | * return an ASCONF_ACK chunk to be sent in response. |
2504 | */ | 2550 | */ |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 177528ed3e1b..a583d67cab63 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -90,6 +90,11 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
90 | const sctp_subtype_t type, | 90 | const sctp_subtype_t type, |
91 | void *arg, | 91 | void *arg, |
92 | sctp_cmd_seq_t *commands); | 92 | sctp_cmd_seq_t *commands); |
93 | static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, | ||
94 | const struct sctp_association *asoc, | ||
95 | const sctp_subtype_t type, | ||
96 | void *arg, | ||
97 | sctp_cmd_seq_t *commands); | ||
93 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); | 98 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); |
94 | 99 | ||
95 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | 100 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, |
@@ -98,6 +103,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | |||
98 | struct sctp_transport *transport); | 103 | struct sctp_transport *transport); |
99 | 104 | ||
100 | static sctp_disposition_t sctp_sf_abort_violation( | 105 | static sctp_disposition_t sctp_sf_abort_violation( |
106 | const struct sctp_endpoint *ep, | ||
101 | const struct sctp_association *asoc, | 107 | const struct sctp_association *asoc, |
102 | void *arg, | 108 | void *arg, |
103 | sctp_cmd_seq_t *commands, | 109 | sctp_cmd_seq_t *commands, |
@@ -111,6 +117,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
111 | void *arg, | 117 | void *arg, |
112 | sctp_cmd_seq_t *commands); | 118 | sctp_cmd_seq_t *commands); |
113 | 119 | ||
120 | static sctp_disposition_t sctp_sf_violation_paramlen( | ||
121 | const struct sctp_endpoint *ep, | ||
122 | const struct sctp_association *asoc, | ||
123 | const sctp_subtype_t type, | ||
124 | void *arg, | ||
125 | sctp_cmd_seq_t *commands); | ||
126 | |||
114 | static sctp_disposition_t sctp_sf_violation_ctsn( | 127 | static sctp_disposition_t sctp_sf_violation_ctsn( |
115 | const struct sctp_endpoint *ep, | 128 | const struct sctp_endpoint *ep, |
116 | const struct sctp_association *asoc, | 129 | const struct sctp_association *asoc, |
@@ -118,6 +131,13 @@ static sctp_disposition_t sctp_sf_violation_ctsn( | |||
118 | void *arg, | 131 | void *arg, |
119 | sctp_cmd_seq_t *commands); | 132 | sctp_cmd_seq_t *commands); |
120 | 133 | ||
134 | static sctp_disposition_t sctp_sf_violation_chunk( | ||
135 | const struct sctp_endpoint *ep, | ||
136 | const struct sctp_association *asoc, | ||
137 | const sctp_subtype_t type, | ||
138 | void *arg, | ||
139 | sctp_cmd_seq_t *commands); | ||
140 | |||
121 | /* Small helper function that checks if the chunk length | 141 | /* Small helper function that checks if the chunk length |
122 | * is of the appropriate length. The 'required_length' argument | 142 | * is of the appropriate length. The 'required_length' argument |
123 | * is set to be the size of a specific chunk we are testing. | 143 | * is set to be the size of a specific chunk we are testing. |
@@ -181,16 +201,21 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep, | |||
181 | struct sctp_chunk *chunk = arg; | 201 | struct sctp_chunk *chunk = arg; |
182 | struct sctp_ulpevent *ev; | 202 | struct sctp_ulpevent *ev; |
183 | 203 | ||
204 | if (!sctp_vtag_verify_either(chunk, asoc)) | ||
205 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
206 | |||
184 | /* RFC 2960 6.10 Bundling | 207 | /* RFC 2960 6.10 Bundling |
185 | * | 208 | * |
186 | * An endpoint MUST NOT bundle INIT, INIT ACK or | 209 | * An endpoint MUST NOT bundle INIT, INIT ACK or |
187 | * SHUTDOWN COMPLETE with any other chunks. | 210 | * SHUTDOWN COMPLETE with any other chunks. |
188 | */ | 211 | */ |
189 | if (!chunk->singleton) | 212 | if (!chunk->singleton) |
190 | return SCTP_DISPOSITION_VIOLATION; | 213 | return sctp_sf_violation_chunk(ep, asoc, type, arg, commands); |
191 | 214 | ||
192 | if (!sctp_vtag_verify_either(chunk, asoc)) | 215 | /* Make sure that the SHUTDOWN_COMPLETE chunk has a valid length. */ |
193 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 216 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) |
217 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
218 | commands); | ||
194 | 219 | ||
195 | /* RFC 2960 10.2 SCTP-to-ULP | 220 | /* RFC 2960 10.2 SCTP-to-ULP |
196 | * | 221 | * |
@@ -450,17 +475,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, | |||
450 | if (!sctp_vtag_verify(chunk, asoc)) | 475 | if (!sctp_vtag_verify(chunk, asoc)) |
451 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 476 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
452 | 477 | ||
453 | /* Make sure that the INIT-ACK chunk has a valid length */ | ||
454 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t))) | ||
455 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
456 | commands); | ||
457 | /* 6.10 Bundling | 478 | /* 6.10 Bundling |
458 | * An endpoint MUST NOT bundle INIT, INIT ACK or | 479 | * An endpoint MUST NOT bundle INIT, INIT ACK or |
459 | * SHUTDOWN COMPLETE with any other chunks. | 480 | * SHUTDOWN COMPLETE with any other chunks. |
460 | */ | 481 | */ |
461 | if (!chunk->singleton) | 482 | if (!chunk->singleton) |
462 | return SCTP_DISPOSITION_VIOLATION; | 483 | return sctp_sf_violation_chunk(ep, asoc, type, arg, commands); |
463 | 484 | ||
485 | /* Make sure that the INIT-ACK chunk has a valid length */ | ||
486 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t))) | ||
487 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
488 | commands); | ||
464 | /* Grab the INIT header. */ | 489 | /* Grab the INIT header. */ |
465 | chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; | 490 | chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; |
466 | 491 | ||
@@ -585,7 +610,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
585 | * control endpoint, respond with an ABORT. | 610 | * control endpoint, respond with an ABORT. |
586 | */ | 611 | */ |
587 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) | 612 | if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) |
588 | return sctp_sf_ootb(ep, asoc, type, arg, commands); | 613 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
589 | 614 | ||
590 | /* Make sure that the COOKIE_ECHO chunk has a valid length. | 615 | /* Make sure that the COOKIE_ECHO chunk has a valid length. |
591 | * In this case, we check that we have enough for at least a | 616 | * In this case, we check that we have enough for at least a |
@@ -2496,6 +2521,11 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep, | |||
2496 | struct sctp_chunk *chunk = (struct sctp_chunk *) arg; | 2521 | struct sctp_chunk *chunk = (struct sctp_chunk *) arg; |
2497 | struct sctp_chunk *reply; | 2522 | struct sctp_chunk *reply; |
2498 | 2523 | ||
2524 | /* Make sure that the chunk has a valid length */ | ||
2525 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | ||
2526 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
2527 | commands); | ||
2528 | |||
2499 | /* Since we are not going to really process this INIT, there | 2529 | /* Since we are not going to really process this INIT, there |
2500 | * is no point in verifying chunk boundries. Just generate | 2530 | * is no point in verifying chunk boundries. Just generate |
2501 | * the SHUTDOWN ACK. | 2531 | * the SHUTDOWN ACK. |
@@ -2929,7 +2959,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, | |||
2929 | * | 2959 | * |
2930 | * The return value is the disposition of the chunk. | 2960 | * The return value is the disposition of the chunk. |
2931 | */ | 2961 | */ |
2932 | sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, | 2962 | static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, |
2933 | const struct sctp_association *asoc, | 2963 | const struct sctp_association *asoc, |
2934 | const sctp_subtype_t type, | 2964 | const sctp_subtype_t type, |
2935 | void *arg, | 2965 | void *arg, |
@@ -2965,6 +2995,7 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, | |||
2965 | 2995 | ||
2966 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 2996 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); |
2967 | 2997 | ||
2998 | sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
2968 | return SCTP_DISPOSITION_CONSUME; | 2999 | return SCTP_DISPOSITION_CONSUME; |
2969 | } | 3000 | } |
2970 | 3001 | ||
@@ -3125,14 +3156,14 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3125 | 3156 | ||
3126 | ch = (sctp_chunkhdr_t *) chunk->chunk_hdr; | 3157 | ch = (sctp_chunkhdr_t *) chunk->chunk_hdr; |
3127 | do { | 3158 | do { |
3128 | /* Break out if chunk length is less then minimal. */ | 3159 | /* Report violation if the chunk is less then minimal */ |
3129 | if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) | 3160 | if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) |
3130 | break; | 3161 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, |
3131 | 3162 | commands); | |
3132 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | ||
3133 | if (ch_end > skb_tail_pointer(skb)) | ||
3134 | break; | ||
3135 | 3163 | ||
3164 | /* Now that we know we at least have a chunk header, | ||
3165 | * do things that are type appropriate. | ||
3166 | */ | ||
3136 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) | 3167 | if (SCTP_CID_SHUTDOWN_ACK == ch->type) |
3137 | ootb_shut_ack = 1; | 3168 | ootb_shut_ack = 1; |
3138 | 3169 | ||
@@ -3144,15 +3175,19 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3144 | if (SCTP_CID_ABORT == ch->type) | 3175 | if (SCTP_CID_ABORT == ch->type) |
3145 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3176 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3146 | 3177 | ||
3178 | /* Report violation if chunk len overflows */ | ||
3179 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | ||
3180 | if (ch_end > skb_tail_pointer(skb)) | ||
3181 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
3182 | commands); | ||
3183 | |||
3147 | ch = (sctp_chunkhdr_t *) ch_end; | 3184 | ch = (sctp_chunkhdr_t *) ch_end; |
3148 | } while (ch_end < skb_tail_pointer(skb)); | 3185 | } while (ch_end < skb_tail_pointer(skb)); |
3149 | 3186 | ||
3150 | if (ootb_shut_ack) | 3187 | if (ootb_shut_ack) |
3151 | sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); | 3188 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); |
3152 | else | 3189 | else |
3153 | sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 3190 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
3154 | |||
3155 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3156 | } | 3191 | } |
3157 | 3192 | ||
3158 | /* | 3193 | /* |
@@ -3218,7 +3253,11 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
3218 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | 3253 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) |
3219 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3254 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3220 | 3255 | ||
3221 | return SCTP_DISPOSITION_CONSUME; | 3256 | /* We need to discard the rest of the packet to prevent |
3257 | * potential bomming attacks from additional bundled chunks. | ||
3258 | * This is documented in SCTP Threats ID. | ||
3259 | */ | ||
3260 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3222 | } | 3261 | } |
3223 | 3262 | ||
3224 | return SCTP_DISPOSITION_NOMEM; | 3263 | return SCTP_DISPOSITION_NOMEM; |
@@ -3241,6 +3280,13 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep, | |||
3241 | void *arg, | 3280 | void *arg, |
3242 | sctp_cmd_seq_t *commands) | 3281 | sctp_cmd_seq_t *commands) |
3243 | { | 3282 | { |
3283 | struct sctp_chunk *chunk = arg; | ||
3284 | |||
3285 | /* Make sure that the SHUTDOWN_ACK chunk has a valid length. */ | ||
3286 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | ||
3287 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
3288 | commands); | ||
3289 | |||
3244 | /* Although we do have an association in this case, it corresponds | 3290 | /* Although we do have an association in this case, it corresponds |
3245 | * to a restarted association. So the packet is treated as an OOTB | 3291 | * to a restarted association. So the packet is treated as an OOTB |
3246 | * packet and the state function that handles OOTB SHUTDOWN_ACK is | 3292 | * packet and the state function that handles OOTB SHUTDOWN_ACK is |
@@ -3257,8 +3303,11 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
3257 | { | 3303 | { |
3258 | struct sctp_chunk *chunk = arg; | 3304 | struct sctp_chunk *chunk = arg; |
3259 | struct sctp_chunk *asconf_ack = NULL; | 3305 | struct sctp_chunk *asconf_ack = NULL; |
3306 | struct sctp_paramhdr *err_param = NULL; | ||
3260 | sctp_addiphdr_t *hdr; | 3307 | sctp_addiphdr_t *hdr; |
3308 | union sctp_addr_param *addr_param; | ||
3261 | __u32 serial; | 3309 | __u32 serial; |
3310 | int length; | ||
3262 | 3311 | ||
3263 | if (!sctp_vtag_verify(chunk, asoc)) { | 3312 | if (!sctp_vtag_verify(chunk, asoc)) { |
3264 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, | 3313 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, |
@@ -3274,6 +3323,20 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep, | |||
3274 | hdr = (sctp_addiphdr_t *)chunk->skb->data; | 3323 | hdr = (sctp_addiphdr_t *)chunk->skb->data; |
3275 | serial = ntohl(hdr->serial); | 3324 | serial = ntohl(hdr->serial); |
3276 | 3325 | ||
3326 | addr_param = (union sctp_addr_param *)hdr->params; | ||
3327 | length = ntohs(addr_param->p.length); | ||
3328 | if (length < sizeof(sctp_paramhdr_t)) | ||
3329 | return sctp_sf_violation_paramlen(ep, asoc, type, | ||
3330 | (void *)addr_param, commands); | ||
3331 | |||
3332 | /* Verify the ASCONF chunk before processing it. */ | ||
3333 | if (!sctp_verify_asconf(asoc, | ||
3334 | (sctp_paramhdr_t *)((void *)addr_param + length), | ||
3335 | (void *)chunk->chunk_end, | ||
3336 | &err_param)) | ||
3337 | return sctp_sf_violation_paramlen(ep, asoc, type, | ||
3338 | (void *)&err_param, commands); | ||
3339 | |||
3277 | /* ADDIP 4.2 C1) Compare the value of the serial number to the value | 3340 | /* ADDIP 4.2 C1) Compare the value of the serial number to the value |
3278 | * the endpoint stored in a new association variable | 3341 | * the endpoint stored in a new association variable |
3279 | * 'Peer-Serial-Number'. | 3342 | * 'Peer-Serial-Number'. |
@@ -3328,6 +3391,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3328 | struct sctp_chunk *asconf_ack = arg; | 3391 | struct sctp_chunk *asconf_ack = arg; |
3329 | struct sctp_chunk *last_asconf = asoc->addip_last_asconf; | 3392 | struct sctp_chunk *last_asconf = asoc->addip_last_asconf; |
3330 | struct sctp_chunk *abort; | 3393 | struct sctp_chunk *abort; |
3394 | struct sctp_paramhdr *err_param = NULL; | ||
3331 | sctp_addiphdr_t *addip_hdr; | 3395 | sctp_addiphdr_t *addip_hdr; |
3332 | __u32 sent_serial, rcvd_serial; | 3396 | __u32 sent_serial, rcvd_serial; |
3333 | 3397 | ||
@@ -3345,6 +3409,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep, | |||
3345 | addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data; | 3409 | addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data; |
3346 | rcvd_serial = ntohl(addip_hdr->serial); | 3410 | rcvd_serial = ntohl(addip_hdr->serial); |
3347 | 3411 | ||
3412 | /* Verify the ASCONF-ACK chunk before processing it. */ | ||
3413 | if (!sctp_verify_asconf(asoc, | ||
3414 | (sctp_paramhdr_t *)addip_hdr->params, | ||
3415 | (void *)asconf_ack->chunk_end, | ||
3416 | &err_param)) | ||
3417 | return sctp_sf_violation_paramlen(ep, asoc, type, | ||
3418 | (void *)&err_param, commands); | ||
3419 | |||
3348 | if (last_asconf) { | 3420 | if (last_asconf) { |
3349 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; | 3421 | addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; |
3350 | sent_serial = ntohl(addip_hdr->serial); | 3422 | sent_serial = ntohl(addip_hdr->serial); |
@@ -3655,6 +3727,16 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep, | |||
3655 | void *arg, | 3727 | void *arg, |
3656 | sctp_cmd_seq_t *commands) | 3728 | sctp_cmd_seq_t *commands) |
3657 | { | 3729 | { |
3730 | struct sctp_chunk *chunk = arg; | ||
3731 | |||
3732 | /* Make sure that the chunk has a valid length. | ||
3733 | * Since we don't know the chunk type, we use a general | ||
3734 | * chunkhdr structure to make a comparison. | ||
3735 | */ | ||
3736 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | ||
3737 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
3738 | commands); | ||
3739 | |||
3658 | SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk); | 3740 | SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk); |
3659 | return SCTP_DISPOSITION_DISCARD; | 3741 | return SCTP_DISPOSITION_DISCARD; |
3660 | } | 3742 | } |
@@ -3710,6 +3792,13 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, | |||
3710 | void *arg, | 3792 | void *arg, |
3711 | sctp_cmd_seq_t *commands) | 3793 | sctp_cmd_seq_t *commands) |
3712 | { | 3794 | { |
3795 | struct sctp_chunk *chunk = arg; | ||
3796 | |||
3797 | /* Make sure that the chunk has a valid length. */ | ||
3798 | if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) | ||
3799 | return sctp_sf_violation_chunklen(ep, asoc, type, arg, | ||
3800 | commands); | ||
3801 | |||
3713 | return SCTP_DISPOSITION_VIOLATION; | 3802 | return SCTP_DISPOSITION_VIOLATION; |
3714 | } | 3803 | } |
3715 | 3804 | ||
@@ -3717,12 +3806,14 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, | |||
3717 | * Common function to handle a protocol violation. | 3806 | * Common function to handle a protocol violation. |
3718 | */ | 3807 | */ |
3719 | static sctp_disposition_t sctp_sf_abort_violation( | 3808 | static sctp_disposition_t sctp_sf_abort_violation( |
3809 | const struct sctp_endpoint *ep, | ||
3720 | const struct sctp_association *asoc, | 3810 | const struct sctp_association *asoc, |
3721 | void *arg, | 3811 | void *arg, |
3722 | sctp_cmd_seq_t *commands, | 3812 | sctp_cmd_seq_t *commands, |
3723 | const __u8 *payload, | 3813 | const __u8 *payload, |
3724 | const size_t paylen) | 3814 | const size_t paylen) |
3725 | { | 3815 | { |
3816 | struct sctp_packet *packet = NULL; | ||
3726 | struct sctp_chunk *chunk = arg; | 3817 | struct sctp_chunk *chunk = arg; |
3727 | struct sctp_chunk *abort = NULL; | 3818 | struct sctp_chunk *abort = NULL; |
3728 | 3819 | ||
@@ -3731,30 +3822,51 @@ static sctp_disposition_t sctp_sf_abort_violation( | |||
3731 | if (!abort) | 3822 | if (!abort) |
3732 | goto nomem; | 3823 | goto nomem; |
3733 | 3824 | ||
3734 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); | 3825 | if (asoc) { |
3735 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 3826 | sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); |
3827 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | ||
3736 | 3828 | ||
3737 | if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { | 3829 | if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { |
3738 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 3830 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
3739 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); | 3831 | SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); |
3740 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 3832 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, |
3741 | SCTP_ERROR(ECONNREFUSED)); | 3833 | SCTP_ERROR(ECONNREFUSED)); |
3742 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, | 3834 | sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, |
3743 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); | 3835 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); |
3836 | } else { | ||
3837 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
3838 | SCTP_ERROR(ECONNABORTED)); | ||
3839 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
3840 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); | ||
3841 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
3842 | } | ||
3744 | } else { | 3843 | } else { |
3745 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 3844 | packet = sctp_ootb_pkt_new(asoc, chunk); |
3746 | SCTP_ERROR(ECONNABORTED)); | 3845 | |
3747 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 3846 | if (!packet) |
3748 | SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); | 3847 | goto nomem_pkt; |
3749 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | 3848 | |
3849 | if (sctp_test_T_bit(abort)) | ||
3850 | packet->vtag = ntohl(chunk->sctp_hdr->vtag); | ||
3851 | |||
3852 | abort->skb->sk = ep->base.sk; | ||
3853 | |||
3854 | sctp_packet_append_chunk(packet, abort); | ||
3855 | |||
3856 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, | ||
3857 | SCTP_PACKET(packet)); | ||
3858 | |||
3859 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | ||
3750 | } | 3860 | } |
3751 | 3861 | ||
3752 | sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); | 3862 | sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); |
3753 | 3863 | ||
3754 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 3864 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); |
3755 | 3865 | ||
3756 | return SCTP_DISPOSITION_ABORT; | 3866 | return SCTP_DISPOSITION_ABORT; |
3757 | 3867 | ||
3868 | nomem_pkt: | ||
3869 | sctp_chunk_free(abort); | ||
3758 | nomem: | 3870 | nomem: |
3759 | return SCTP_DISPOSITION_NOMEM; | 3871 | return SCTP_DISPOSITION_NOMEM; |
3760 | } | 3872 | } |
@@ -3787,7 +3899,24 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
3787 | { | 3899 | { |
3788 | char err_str[]="The following chunk had invalid length:"; | 3900 | char err_str[]="The following chunk had invalid length:"; |
3789 | 3901 | ||
3790 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | 3902 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, |
3903 | sizeof(err_str)); | ||
3904 | } | ||
3905 | |||
3906 | /* | ||
3907 | * Handle a protocol violation when the parameter length is invalid. | ||
3908 | * "Invalid" length is identified as smaller then the minimal length a | ||
3909 | * given parameter can be. | ||
3910 | */ | ||
3911 | static sctp_disposition_t sctp_sf_violation_paramlen( | ||
3912 | const struct sctp_endpoint *ep, | ||
3913 | const struct sctp_association *asoc, | ||
3914 | const sctp_subtype_t type, | ||
3915 | void *arg, | ||
3916 | sctp_cmd_seq_t *commands) { | ||
3917 | char err_str[] = "The following parameter had invalid length:"; | ||
3918 | |||
3919 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, | ||
3791 | sizeof(err_str)); | 3920 | sizeof(err_str)); |
3792 | } | 3921 | } |
3793 | 3922 | ||
@@ -3806,10 +3935,31 @@ static sctp_disposition_t sctp_sf_violation_ctsn( | |||
3806 | { | 3935 | { |
3807 | char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; | 3936 | char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; |
3808 | 3937 | ||
3809 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | 3938 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, |
3810 | sizeof(err_str)); | 3939 | sizeof(err_str)); |
3811 | } | 3940 | } |
3812 | 3941 | ||
3942 | /* Handle protocol violation of an invalid chunk bundling. For example, | ||
3943 | * when we have an association and we recieve bundled INIT-ACK, or | ||
3944 | * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle" | ||
3945 | * statement from the specs. Additinally, there might be an attacker | ||
3946 | * on the path and we may not want to continue this communication. | ||
3947 | */ | ||
3948 | static sctp_disposition_t sctp_sf_violation_chunk( | ||
3949 | const struct sctp_endpoint *ep, | ||
3950 | const struct sctp_association *asoc, | ||
3951 | const sctp_subtype_t type, | ||
3952 | void *arg, | ||
3953 | sctp_cmd_seq_t *commands) | ||
3954 | { | ||
3955 | char err_str[]="The following chunk violates protocol:"; | ||
3956 | |||
3957 | if (!asoc) | ||
3958 | return sctp_sf_violation(ep, asoc, type, arg, commands); | ||
3959 | |||
3960 | return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, | ||
3961 | sizeof(err_str)); | ||
3962 | } | ||
3813 | /*************************************************************************** | 3963 | /*************************************************************************** |
3814 | * These are the state functions for handling primitive (Section 10) events. | 3964 | * These are the state functions for handling primitive (Section 10) events. |
3815 | ***************************************************************************/ | 3965 | ***************************************************************************/ |
@@ -5176,7 +5326,22 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc | |||
5176 | * association exists, otherwise, use the peer's vtag. | 5326 | * association exists, otherwise, use the peer's vtag. |
5177 | */ | 5327 | */ |
5178 | if (asoc) { | 5328 | if (asoc) { |
5179 | vtag = asoc->peer.i.init_tag; | 5329 | /* Special case the INIT-ACK as there is no peer's vtag |
5330 | * yet. | ||
5331 | */ | ||
5332 | switch(chunk->chunk_hdr->type) { | ||
5333 | case SCTP_CID_INIT_ACK: | ||
5334 | { | ||
5335 | sctp_initack_chunk_t *initack; | ||
5336 | |||
5337 | initack = (sctp_initack_chunk_t *)chunk->chunk_hdr; | ||
5338 | vtag = ntohl(initack->init_hdr.init_tag); | ||
5339 | break; | ||
5340 | } | ||
5341 | default: | ||
5342 | vtag = asoc->peer.i.init_tag; | ||
5343 | break; | ||
5344 | } | ||
5180 | } else { | 5345 | } else { |
5181 | /* Special case the INIT and stale COOKIE_ECHO as there is no | 5346 | /* Special case the INIT and stale COOKIE_ECHO as there is no |
5182 | * vtag yet. | 5347 | * vtag yet. |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 70a91ece3c49..ddb0ba3974b0 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
@@ -110,7 +110,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
110 | /* SCTP_STATE_EMPTY */ \ | 110 | /* SCTP_STATE_EMPTY */ \ |
111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 111 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
112 | /* SCTP_STATE_CLOSED */ \ | 112 | /* SCTP_STATE_CLOSED */ \ |
113 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 113 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
114 | /* SCTP_STATE_COOKIE_WAIT */ \ | 114 | /* SCTP_STATE_COOKIE_WAIT */ \ |
115 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 115 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
116 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 116 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -173,7 +173,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
173 | /* SCTP_STATE_EMPTY */ \ | 173 | /* SCTP_STATE_EMPTY */ \ |
174 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 174 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
175 | /* SCTP_STATE_CLOSED */ \ | 175 | /* SCTP_STATE_CLOSED */ \ |
176 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 176 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
177 | /* SCTP_STATE_COOKIE_WAIT */ \ | 177 | /* SCTP_STATE_COOKIE_WAIT */ \ |
178 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 178 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
179 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 179 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -194,7 +194,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
194 | /* SCTP_STATE_EMPTY */ \ | 194 | /* SCTP_STATE_EMPTY */ \ |
195 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 195 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
196 | /* SCTP_STATE_CLOSED */ \ | 196 | /* SCTP_STATE_CLOSED */ \ |
197 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 197 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
198 | /* SCTP_STATE_COOKIE_WAIT */ \ | 198 | /* SCTP_STATE_COOKIE_WAIT */ \ |
199 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 199 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
200 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 200 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -216,7 +216,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
216 | /* SCTP_STATE_EMPTY */ \ | 216 | /* SCTP_STATE_EMPTY */ \ |
217 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 217 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
218 | /* SCTP_STATE_CLOSED */ \ | 218 | /* SCTP_STATE_CLOSED */ \ |
219 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 219 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
220 | /* SCTP_STATE_COOKIE_WAIT */ \ | 220 | /* SCTP_STATE_COOKIE_WAIT */ \ |
221 | TYPE_SCTP_FUNC(sctp_sf_violation), \ | 221 | TYPE_SCTP_FUNC(sctp_sf_violation), \ |
222 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 222 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -258,7 +258,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
258 | /* SCTP_STATE_EMPTY */ \ | 258 | /* SCTP_STATE_EMPTY */ \ |
259 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 259 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
260 | /* SCTP_STATE_CLOSED */ \ | 260 | /* SCTP_STATE_CLOSED */ \ |
261 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 261 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
262 | /* SCTP_STATE_COOKIE_WAIT */ \ | 262 | /* SCTP_STATE_COOKIE_WAIT */ \ |
263 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 263 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
264 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 264 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -300,7 +300,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
300 | /* SCTP_STATE_EMPTY */ \ | 300 | /* SCTP_STATE_EMPTY */ \ |
301 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 301 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
302 | /* SCTP_STATE_CLOSED */ \ | 302 | /* SCTP_STATE_CLOSED */ \ |
303 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 303 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
304 | /* SCTP_STATE_COOKIE_WAIT */ \ | 304 | /* SCTP_STATE_COOKIE_WAIT */ \ |
305 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 305 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
306 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 306 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -499,7 +499,7 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_ | |||
499 | /* SCTP_STATE_EMPTY */ \ | 499 | /* SCTP_STATE_EMPTY */ \ |
500 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ | 500 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
501 | /* SCTP_STATE_CLOSED */ \ | 501 | /* SCTP_STATE_CLOSED */ \ |
502 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ | 502 | TYPE_SCTP_FUNC(sctp_sf_ootb), \ |
503 | /* SCTP_STATE_COOKIE_WAIT */ \ | 503 | /* SCTP_STATE_COOKIE_WAIT */ \ |
504 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ | 504 | TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ |
505 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 505 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
@@ -528,7 +528,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
528 | /* SCTP_STATE_EMPTY */ | 528 | /* SCTP_STATE_EMPTY */ |
529 | TYPE_SCTP_FUNC(sctp_sf_ootb), | 529 | TYPE_SCTP_FUNC(sctp_sf_ootb), |
530 | /* SCTP_STATE_CLOSED */ | 530 | /* SCTP_STATE_CLOSED */ |
531 | TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), | 531 | TYPE_SCTP_FUNC(sctp_sf_ootb), |
532 | /* SCTP_STATE_COOKIE_WAIT */ | 532 | /* SCTP_STATE_COOKIE_WAIT */ |
533 | TYPE_SCTP_FUNC(sctp_sf_unk_chunk), | 533 | TYPE_SCTP_FUNC(sctp_sf_unk_chunk), |
534 | /* SCTP_STATE_COOKIE_ECHOED */ | 534 | /* SCTP_STATE_COOKIE_ECHOED */ |
diff --git a/net/socket.c b/net/socket.c index 7d44453dfae1..b09eb9036a17 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -777,9 +777,6 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
777 | if (pos != 0) | 777 | if (pos != 0) |
778 | return -ESPIPE; | 778 | return -ESPIPE; |
779 | 779 | ||
780 | if (iocb->ki_left == 0) /* Match SYS5 behaviour */ | ||
781 | return 0; | ||
782 | |||
783 | x = alloc_sock_iocb(iocb, &siocb); | 780 | x = alloc_sock_iocb(iocb, &siocb); |
784 | if (!x) | 781 | if (!x) |
785 | return -ENOMEM; | 782 | return -ENOMEM; |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 1a899924023f..036ab520df21 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -1110,7 +1110,8 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
1110 | serv->sv_name); | 1110 | serv->sv_name); |
1111 | printk(KERN_NOTICE | 1111 | printk(KERN_NOTICE |
1112 | "%s: last TCP connect from %s\n", | 1112 | "%s: last TCP connect from %s\n", |
1113 | serv->sv_name, buf); | 1113 | serv->sv_name, __svc_print_addr(sin, |
1114 | buf, sizeof(buf))); | ||
1114 | } | 1115 | } |
1115 | /* | 1116 | /* |
1116 | * Always select the oldest socket. It's not fair, | 1117 | * Always select the oldest socket. It's not fair, |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 7eabd55417a5..9771451eae21 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -213,7 +213,7 @@ out_fail_notifier: | |||
213 | out_fail_sysfs: | 213 | out_fail_sysfs: |
214 | return err; | 214 | return err; |
215 | } | 215 | } |
216 | module_init(cfg80211_init); | 216 | subsys_initcall(cfg80211_init); |
217 | 217 | ||
218 | static void cfg80211_exit(void) | 218 | static void cfg80211_exit(void) |
219 | { | 219 | { |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 88aaacd9f822..2d5d2255a27c 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -52,12 +52,14 @@ static void wiphy_dev_release(struct device *dev) | |||
52 | cfg80211_dev_free(rdev); | 52 | cfg80211_dev_free(rdev); |
53 | } | 53 | } |
54 | 54 | ||
55 | #ifdef CONFIG_HOTPLUG | ||
55 | static int wiphy_uevent(struct device *dev, char **envp, | 56 | static int wiphy_uevent(struct device *dev, char **envp, |
56 | int num_envp, char *buf, int size) | 57 | int num_envp, char *buf, int size) |
57 | { | 58 | { |
58 | /* TODO, we probably need stuff here */ | 59 | /* TODO, we probably need stuff here */ |
59 | return 0; | 60 | return 0; |
60 | } | 61 | } |
62 | #endif | ||
61 | 63 | ||
62 | struct class ieee80211_class = { | 64 | struct class ieee80211_class = { |
63 | .name = "ieee80211", | 65 | .name = "ieee80211", |