Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
netns: Don't receive new packets in a dead network namespace.
sctp: Make sure N * sizeof(union sctp_addr) does not overflow.
pppoe: warning fix
ipv6: Drop packets for loopback address from outside of the box.
ipv6: Remove options header when setsockopt's optlen is 0
mac80211: detect driver tx bugs

+52 -7
+1 -1
drivers/net/pppoe.c
··· 942 m->msg_namelen = 0; 943 944 if (skb) { 945 - total_len = min(total_len, skb->len); 946 error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); 947 if (error == 0) 948 error = total_len;
··· 942 m->msg_namelen = 0; 943 944 if (skb) { 945 + total_len = min_t(size_t, total_len, skb->len); 946 error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); 947 if (error == 0) 948 error = total_len;
+6
include/net/ipv6.h
··· 367 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 368 } 369 370 static inline int ipv6_addr_v4mapped(const struct in6_addr *a) 371 { 372 return ((a->s6_addr32[0] | a->s6_addr32[1] |
··· 367 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 368 } 369 370 + static inline int ipv6_addr_loopback(const struct in6_addr *a) 371 + { 372 + return ((a->s6_addr32[0] | a->s6_addr32[1] | 373 + a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); 374 + } 375 + 376 static inline int ipv6_addr_v4mapped(const struct in6_addr *a) 377 { 378 return ((a->s6_addr32[0] | a->s6_addr32[1] |
+11
include/net/net_namespace.h
··· 95 #ifdef CONFIG_NET_NS 96 extern void __put_net(struct net *net); 97 98 static inline struct net *get_net(struct net *net) 99 { 100 atomic_inc(&net->count); ··· 130 return net1 == net2; 131 } 132 #else 133 static inline struct net *get_net(struct net *net) 134 { 135 return net;
··· 95 #ifdef CONFIG_NET_NS 96 extern void __put_net(struct net *net); 97 98 + static inline int net_alive(struct net *net) 99 + { 100 + return net && atomic_read(&net->count); 101 + } 102 + 103 static inline struct net *get_net(struct net *net) 104 { 105 atomic_inc(&net->count); ··· 125 return net1 == net2; 126 } 127 #else 128 + 129 + static inline int net_alive(struct net *net) 130 + { 131 + return 1; 132 + } 133 + 134 static inline struct net *get_net(struct net *net) 135 { 136 return net;
+4
net/core/dev.c
··· 2077 2078 rcu_read_lock(); 2079 2080 #ifdef CONFIG_NET_CLS_ACT 2081 if (skb->tc_verd & TC_NCLS) { 2082 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
··· 2077 2078 rcu_read_lock(); 2079 2080 + /* Don't receive packets in an exiting network namespace */ 2081 + if (!net_alive(dev_net(skb->dev))) 2082 + goto out; 2083 + 2084 #ifdef CONFIG_NET_CLS_ACT 2085 if (skb->tc_verd & TC_NCLS) { 2086 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
+3
net/core/net_namespace.c
··· 140 struct pernet_operations *ops; 141 struct net *net; 142 143 net = container_of(work, struct net, work); 144 145 mutex_lock(&net_mutex);
··· 140 struct pernet_operations *ops; 141 struct net *net; 142 143 + /* Be very certain incoming network packets will not find us */ 144 + rcu_barrier(); 145 + 146 net = container_of(work, struct net, work); 147 148 mutex_lock(&net_mutex);
+9
net/ipv6/ip6_input.c
··· 102 if (hdr->version != 6) 103 goto err; 104 105 skb->transport_header = skb->network_header + sizeof(*hdr); 106 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); 107
··· 102 if (hdr->version != 6) 103 goto err; 104 105 + /* 106 + * RFC4291 2.5.3 107 + * A packet received on an interface with a destination address 108 + * of loopback must be dropped. 109 + */ 110 + if (!(dev->flags & IFF_LOOPBACK) && 111 + ipv6_addr_loopback(&hdr->daddr)) 112 + goto err; 113 + 114 skb->transport_header = skb->network_header + sizeof(*hdr); 115 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); 116
+7 -4
net/ipv6/ipv6_sockglue.c
··· 345 case IPV6_DSTOPTS: 346 { 347 struct ipv6_txoptions *opt; 348 if (optlen == 0) 349 optval = NULL; 350 351 /* hop-by-hop / destination options are privileged option */ 352 retv = -EPERM; 353 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) 354 break; 355 - 356 - if (optlen < sizeof(struct ipv6_opt_hdr) || 357 - optlen & 0x7 || optlen > 8 * 255) 358 - goto e_inval; 359 360 opt = ipv6_renew_options(sk, np->opt, optname, 361 (struct ipv6_opt_hdr __user *)optval,
··· 345 case IPV6_DSTOPTS: 346 { 347 struct ipv6_txoptions *opt; 348 + 349 + /* remove any sticky options header with a zero option 350 + * length, per RFC3542. 351 + */ 352 if (optlen == 0) 353 optval = NULL; 354 + else if (optlen < sizeof(struct ipv6_opt_hdr) || 355 + optlen & 0x7 || optlen > 8 * 255) 356 + goto e_inval; 357 358 /* hop-by-hop / destination options are privileged option */ 359 retv = -EPERM; 360 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) 361 break; 362 363 opt = ipv6_renew_options(sk, np->opt, optname, 364 (struct ipv6_opt_hdr __user *)optval,
+8 -1
net/mac80211/tx.c
··· 1132 ieee80211_tx_handler *handler; 1133 struct ieee80211_tx_data tx; 1134 ieee80211_tx_result res = TX_DROP, res_prepare; 1135 - int ret, i; 1136 1137 WARN_ON(__ieee80211_queue_pending(local, control->queue)); 1138 ··· 1216 if (!__ieee80211_queue_stopped(local, control->queue)) { 1217 clear_bit(IEEE80211_LINK_STATE_PENDING, 1218 &local->state[control->queue]); 1219 goto retry; 1220 } 1221 memcpy(&store->control, control,
··· 1132 ieee80211_tx_handler *handler; 1133 struct ieee80211_tx_data tx; 1134 ieee80211_tx_result res = TX_DROP, res_prepare; 1135 + int ret, i, retries = 0; 1136 1137 WARN_ON(__ieee80211_queue_pending(local, control->queue)); 1138 ··· 1216 if (!__ieee80211_queue_stopped(local, control->queue)) { 1217 clear_bit(IEEE80211_LINK_STATE_PENDING, 1218 &local->state[control->queue]); 1219 + retries++; 1220 + /* 1221 + * Driver bug, it's rejecting packets but 1222 + * not stopping queues. 1223 + */ 1224 + if (WARN_ON_ONCE(retries > 5)) 1225 + goto drop; 1226 goto retry; 1227 } 1228 memcpy(&store->control, control,
+3 -1
net/sctp/socket.c
··· 4401 if (copy_from_user(&getaddrs, optval, len)) 4402 return -EFAULT; 4403 4404 - if (getaddrs.addr_num <= 0) return -EINVAL; 4405 /* 4406 * For UDP-style sockets, id specifies the association to query. 4407 * If the id field is set to the value '0' then the locally bound
··· 4401 if (copy_from_user(&getaddrs, optval, len)) 4402 return -EFAULT; 4403 4404 + if (getaddrs.addr_num <= 0 || 4405 + getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) 4406 + return -EINVAL; 4407 /* 4408 * For UDP-style sockets, id specifies the association to query. 4409 * If the id field is set to the value '0' then the locally bound