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