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 | 56 | ||||
| -rw-r--r-- | net/ipv4/tcp_input.c | 3 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 19 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 9 | ||||
| -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/rose/rose_loopback.c | 4 | ||||
| -rw-r--r-- | net/rose/rose_route.c | 15 | ||||
| -rw-r--r-- | net/sched/cls_u32.c | 2 | ||||
| -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 |
25 files changed, 390 insertions, 149 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..5742dc803b79 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; |
| @@ -128,7 +114,7 @@ check_assoc_again: | |||
| 128 | sm->associnfo.associating = 1; | 114 | sm->associnfo.associating = 1; |
| 129 | /* queue lower level code to do work (if necessary) */ | 115 | /* queue lower level code to do work (if necessary) */ |
| 130 | schedule_delayed_work(&sm->associnfo.work, 0); | 116 | schedule_delayed_work(&sm->associnfo.work, 0); |
| 131 | out: | 117 | |
| 132 | mutex_unlock(&sm->associnfo.mutex); | 118 | mutex_unlock(&sm->associnfo.mutex); |
| 133 | 119 | ||
| 134 | return 0; | 120 | return 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_input.c b/net/ipv4/tcp_input.c index bbad2cdb74b7..f893e90061eb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -2420,6 +2420,9 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | |||
| 2420 | __u32 dval = min(tp->fackets_out, packets_acked); | 2420 | __u32 dval = min(tp->fackets_out, packets_acked); |
| 2421 | tp->fackets_out -= dval; | 2421 | tp->fackets_out -= dval; |
| 2422 | } | 2422 | } |
| 2423 | /* hint's skb might be NULL but we don't need to care */ | ||
| 2424 | tp->fastpath_cnt_hint -= min_t(u32, packets_acked, | ||
| 2425 | tp->fastpath_cnt_hint); | ||
| 2423 | tp->packets_out -= packets_acked; | 2426 | tp->packets_out -= packets_acked; |
| 2424 | 2427 | ||
| 2425 | BUG_ON(tcp_skb_pcount(skb) == 0); | 2428 | BUG_ON(tcp_skb_pcount(skb) == 0); |
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/ndisc.c b/net/ipv6/ndisc.c index 73a894a2152c..5b596659177c 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1268,9 +1268,10 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
| 1268 | 1268 | ||
| 1269 | if (ipv6_addr_equal(dest, target)) { | 1269 | if (ipv6_addr_equal(dest, target)) { |
| 1270 | on_link = 1; | 1270 | on_link = 1; |
| 1271 | } else if (!(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { | 1271 | } else if (ipv6_addr_type(target) != |
| 1272 | (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { | ||
| 1272 | ND_PRINTK2(KERN_WARNING | 1273 | ND_PRINTK2(KERN_WARNING |
| 1273 | "ICMPv6 Redirect: target address is not link-local.\n"); | 1274 | "ICMPv6 Redirect: target address is not link-local unicast.\n"); |
| 1274 | return; | 1275 | return; |
| 1275 | } | 1276 | } |
| 1276 | 1277 | ||
| @@ -1344,9 +1345,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
| 1344 | } | 1345 | } |
| 1345 | 1346 | ||
| 1346 | if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && | 1347 | if (!ipv6_addr_equal(&ipv6_hdr(skb)->daddr, target) && |
| 1347 | !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { | 1348 | ipv6_addr_type(target) != (IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) { |
| 1348 | ND_PRINTK2(KERN_WARNING | 1349 | ND_PRINTK2(KERN_WARNING |
| 1349 | "ICMPv6 Redirect: target address is not link-local.\n"); | 1350 | "ICMPv6 Redirect: target address is not link-local unicast.\n"); |
| 1350 | return; | 1351 | return; |
| 1351 | } | 1352 | } |
| 1352 | 1353 | ||
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/rose/rose_loopback.c b/net/rose/rose_loopback.c index cd01642f0491..114df6eec8c3 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c | |||
| @@ -79,7 +79,7 @@ static void rose_loopback_timer(unsigned long param) | |||
| 79 | 79 | ||
| 80 | skb_reset_transport_header(skb); | 80 | skb_reset_transport_header(skb); |
| 81 | 81 | ||
| 82 | sk = rose_find_socket(lci_o, &rose_loopback_neigh); | 82 | sk = rose_find_socket(lci_o, rose_loopback_neigh); |
| 83 | if (sk) { | 83 | if (sk) { |
| 84 | if (rose_process_rx_frame(sk, skb) == 0) | 84 | if (rose_process_rx_frame(sk, skb) == 0) |
| 85 | kfree_skb(skb); | 85 | kfree_skb(skb); |
| @@ -88,7 +88,7 @@ static void rose_loopback_timer(unsigned long param) | |||
| 88 | 88 | ||
| 89 | if (frametype == ROSE_CALL_REQUEST) { | 89 | if (frametype == ROSE_CALL_REQUEST) { |
| 90 | if ((dev = rose_dev_get(dest)) != NULL) { | 90 | if ((dev = rose_dev_get(dest)) != NULL) { |
| 91 | if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0) | 91 | if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) |
| 92 | kfree_skb(skb); | 92 | kfree_skb(skb); |
| 93 | } else { | 93 | } else { |
| 94 | kfree_skb(skb); | 94 | kfree_skb(skb); |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index bbcbad1da0d0..96f61a71b252 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -45,7 +45,7 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock); | |||
| 45 | static struct rose_route *rose_route_list; | 45 | static struct rose_route *rose_route_list; |
| 46 | static DEFINE_SPINLOCK(rose_route_list_lock); | 46 | static DEFINE_SPINLOCK(rose_route_list_lock); |
| 47 | 47 | ||
| 48 | struct rose_neigh rose_loopback_neigh; | 48 | struct rose_neigh *rose_loopback_neigh; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | * Add a new route to a node, and in the process add the node and the | 51 | * Add a new route to a node, and in the process add the node and the |
| @@ -362,7 +362,12 @@ out: | |||
| 362 | */ | 362 | */ |
| 363 | void rose_add_loopback_neigh(void) | 363 | void rose_add_loopback_neigh(void) |
| 364 | { | 364 | { |
| 365 | struct rose_neigh *sn = &rose_loopback_neigh; | 365 | struct rose_neigh *sn; |
| 366 | |||
| 367 | rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL); | ||
| 368 | if (!rose_loopback_neigh) | ||
| 369 | return; | ||
| 370 | sn = rose_loopback_neigh; | ||
| 366 | 371 | ||
| 367 | sn->callsign = null_ax25_address; | 372 | sn->callsign = null_ax25_address; |
| 368 | sn->digipeat = NULL; | 373 | sn->digipeat = NULL; |
| @@ -417,13 +422,13 @@ int rose_add_loopback_node(rose_address *address) | |||
| 417 | rose_node->mask = 10; | 422 | rose_node->mask = 10; |
| 418 | rose_node->count = 1; | 423 | rose_node->count = 1; |
| 419 | rose_node->loopback = 1; | 424 | rose_node->loopback = 1; |
| 420 | rose_node->neighbour[0] = &rose_loopback_neigh; | 425 | rose_node->neighbour[0] = rose_loopback_neigh; |
| 421 | 426 | ||
| 422 | /* Insert at the head of list. Address is always mask=10 */ | 427 | /* Insert at the head of list. Address is always mask=10 */ |
| 423 | rose_node->next = rose_node_list; | 428 | rose_node->next = rose_node_list; |
| 424 | rose_node_list = rose_node; | 429 | rose_node_list = rose_node; |
| 425 | 430 | ||
| 426 | rose_loopback_neigh.count++; | 431 | rose_loopback_neigh->count++; |
| 427 | 432 | ||
| 428 | out: | 433 | out: |
| 429 | spin_unlock_bh(&rose_node_list_lock); | 434 | spin_unlock_bh(&rose_node_list_lock); |
| @@ -454,7 +459,7 @@ void rose_del_loopback_node(rose_address *address) | |||
| 454 | 459 | ||
| 455 | rose_remove_node(rose_node); | 460 | rose_remove_node(rose_node); |
| 456 | 461 | ||
| 457 | rose_loopback_neigh.count--; | 462 | rose_loopback_neigh->count--; |
| 458 | 463 | ||
| 459 | out: | 464 | out: |
| 460 | spin_unlock_bh(&rose_node_list_lock); | 465 | spin_unlock_bh(&rose_node_list_lock); |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 8dbe36912ecb..d4d5d2f271d2 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
| @@ -502,7 +502,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, | |||
| 502 | 502 | ||
| 503 | #ifdef CONFIG_NET_CLS_IND | 503 | #ifdef CONFIG_NET_CLS_IND |
| 504 | if (tb[TCA_U32_INDEV-1]) { | 504 | if (tb[TCA_U32_INDEV-1]) { |
| 505 | int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]); | 505 | err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]); |
| 506 | if (err < 0) | 506 | if (err < 0) |
| 507 | goto errout; | 507 | goto errout; |
| 508 | } | 508 | } |
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", |
