aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-13 16:25:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-13 16:25:36 -0400
commitdbbffe6898fd0d7bac66ded5d3c58835b13ddefc (patch)
treefc69faae77d9fd64139c13691c3895fd87f83111 /net
parent1f638766ffcd9f08209afcabb3e2df961552fe18 (diff)
parentba21fc696dd28ea7a5880345faf0168619a478d2 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "Several small bug fixes all over: 1) be2net driver uses wrong payload length when submitting MAC list get requests to the chip. From Sathya Perla. 2) Fix mwifiex memory leak on driver unload, from Amitkumar Karwar. 3) Prevent random memory access in batman-adv, from Marek Lindner. 4) batman-adv doesn't check for pskb_trim_rcsum() errors, also from Marek Lindner. 5) Fix fec crashes on rapid link up/down, from Frank Li. 6) Fix inner protocol grovelling in GSO, from Pravin B Shelar. 7) Link event validation fix in qlcnic from Rajesh Borundia. 8) Not all FEC chips can support checksum offload, fix from Shawn Guo. 9) EXPORT_SYMBOL + inline doesn't make any sense, from Denis Efremov. 10) Fix race in passthru mode during device removal in macvlan, from Jiri Pirko. 11) Fix RCU hash table lookup socket state race in ipv6, leading to NULL pointer derefs, from Eric Dumazet. 12) Add several missing HAS_DMA kconfig dependencies, from Geert Uyttterhoeven. 13) Fix bogus PCI resource management in 3c59x driver, from Sergei Shtylyov. 14) Fix info leak in ipv6 GRE tunnel driver, from Amerigo Wang. 15) Fix device leak in ipv6 IPSEC policy layer, from Cong Wang. 16) DMA mapping leak fix in qlge from Thadeu Lima de Souza Cascardo. 17) Missing iounmap on probe failure in bna driver, from Wei Yongjun." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (40 commits) bna: add missing iounmap() on error in bnad_init() qlge: fix dma map leak when the last chunk is not allocated xfrm6: release dev before returning error ipv6,gre: do not leak info to user-space virtio_net: use default napi weight by default emac: Fix EMAC soft reset on 460EX/GT 3c59x: fix PCI resource management caif: CAIF_VIRTIO should depend on HAS_DMA net/ethernet: MACB should depend on HAS_DMA net/ethernet: ARM_AT91_ETHER should depend on HAS_DMA net/wireless: ATH9K should depend on HAS_DMA net/ethernet: STMMAC_ETH should depend on HAS_DMA net/ethernet: NET_CALXEDA_XGMAC should depend on HAS_DMA ipv6: do not clear pinet6 field macvlan: fix passthru mode race between dev removal and rx path ipv4: ip_output: remove inline marking of EXPORT_SYMBOL functions net/mlx4: Strengthen VLAN tags/priorities enforcement in VST mode net/mlx4_core: Add missing report on VST and spoof-checking dev caps net: fec: enable hardware checksum only on imx6q-fec qlcnic: Fix validation of link event command. ...
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/distributed-arp-table.c13
-rw-r--r--net/batman-adv/main.c18
-rw-r--r--net/batman-adv/network-coding.c8
-rw-r--r--net/core/sock.c12
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv6/ip6_gre.c2
-rw-r--r--net/ipv6/tcp_ipv6.c12
-rw-r--r--net/ipv6/udp.c13
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/ipv6/xfrm6_policy.c4
11 files changed, 65 insertions, 23 deletions
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 8e15d966d9b0..239992021b1d 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -837,6 +837,19 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
837 837
838 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); 838 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
839 if (dat_entry) { 839 if (dat_entry) {
840 /* If the ARP request is destined for a local client the local
841 * client will answer itself. DAT would only generate a
842 * duplicate packet.
843 *
844 * Moreover, if the soft-interface is enslaved into a bridge, an
845 * additional DAT answer may trigger kernel warnings about
846 * a packet coming from the wrong port.
847 */
848 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
849 ret = true;
850 goto out;
851 }
852
840 skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, 853 skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
841 bat_priv->soft_iface, ip_dst, hw_src, 854 bat_priv->soft_iface, ip_dst, hw_src,
842 dat_entry->mac_addr, hw_src); 855 dat_entry->mac_addr, hw_src);
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 3e30a0f1b908..1240f07ad31d 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface)
163 batadv_vis_quit(bat_priv); 163 batadv_vis_quit(bat_priv);
164 164
165 batadv_gw_node_purge(bat_priv); 165 batadv_gw_node_purge(bat_priv);
166 batadv_originator_free(bat_priv);
167 batadv_nc_free(bat_priv); 166 batadv_nc_free(bat_priv);
167 batadv_dat_free(bat_priv);
168 batadv_bla_free(bat_priv);
168 169
170 /* Free the TT and the originator tables only after having terminated
171 * all the other depending components which may use these structures for
172 * their purposes.
173 */
169 batadv_tt_free(bat_priv); 174 batadv_tt_free(bat_priv);
170 175
171 batadv_bla_free(bat_priv); 176 /* Since the originator table clean up routine is accessing the TT
172 177 * tables as well, it has to be invoked after the TT tables have been
173 batadv_dat_free(bat_priv); 178 * freed and marked as empty. This ensures that no cleanup RCU callbacks
179 * accessing the TT data are scheduled for later execution.
180 */
181 batadv_originator_free(bat_priv);
174 182
175 free_percpu(bat_priv->bat_counters); 183 free_percpu(bat_priv->bat_counters);
176 184
@@ -475,7 +483,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
475 char *algo_name = (char *)val; 483 char *algo_name = (char *)val;
476 size_t name_len = strlen(algo_name); 484 size_t name_len = strlen(algo_name);
477 485
478 if (algo_name[name_len - 1] == '\n') 486 if (name_len > 0 && algo_name[name_len - 1] == '\n')
479 algo_name[name_len - 1] = '\0'; 487 algo_name[name_len - 1] = '\0';
480 488
481 bat_algo_ops = batadv_algo_get(algo_name); 489 bat_algo_ops = batadv_algo_get(algo_name);
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index f7c54305a918..e84629ece9b7 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -1514,6 +1514,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
1514 struct ethhdr *ethhdr, ethhdr_tmp; 1514 struct ethhdr *ethhdr, ethhdr_tmp;
1515 uint8_t *orig_dest, ttl, ttvn; 1515 uint8_t *orig_dest, ttl, ttvn;
1516 unsigned int coding_len; 1516 unsigned int coding_len;
1517 int err;
1517 1518
1518 /* Save headers temporarily */ 1519 /* Save headers temporarily */
1519 memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp)); 1520 memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp));
@@ -1568,8 +1569,11 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
1568 coding_len); 1569 coding_len);
1569 1570
1570 /* Resize decoded skb if decoded with larger packet */ 1571 /* Resize decoded skb if decoded with larger packet */
1571 if (nc_packet->skb->len > coding_len + h_size) 1572 if (nc_packet->skb->len > coding_len + h_size) {
1572 pskb_trim_rcsum(skb, coding_len + h_size); 1573 err = pskb_trim_rcsum(skb, coding_len + h_size);
1574 if (err)
1575 return NULL;
1576 }
1573 1577
1574 /* Create decoded unicast packet */ 1578 /* Create decoded unicast packet */
1575 unicast_packet = (struct batadv_unicast_packet *)skb->data; 1579 unicast_packet = (struct batadv_unicast_packet *)skb->data;
diff --git a/net/core/sock.c b/net/core/sock.c
index d4f4cea726e7..6ba327da79e1 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1217,18 +1217,6 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
1217#endif 1217#endif
1218} 1218}
1219 1219
1220/*
1221 * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
1222 * un-modified. Special care is taken when initializing object to zero.
1223 */
1224static inline void sk_prot_clear_nulls(struct sock *sk, int size)
1225{
1226 if (offsetof(struct sock, sk_node.next) != 0)
1227 memset(sk, 0, offsetof(struct sock, sk_node.next));
1228 memset(&sk->sk_node.pprev, 0,
1229 size - offsetof(struct sock, sk_node.pprev));
1230}
1231
1232void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) 1220void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
1233{ 1221{
1234 unsigned long nulls1, nulls2; 1222 unsigned long nulls1, nulls2;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 147abf5275aa..4bcabf3ab4ca 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -84,7 +84,7 @@ int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
84EXPORT_SYMBOL(sysctl_ip_default_ttl); 84EXPORT_SYMBOL(sysctl_ip_default_ttl);
85 85
86/* Generate a checksum for an outgoing IP datagram. */ 86/* Generate a checksum for an outgoing IP datagram. */
87__inline__ void ip_send_check(struct iphdr *iph) 87void ip_send_check(struct iphdr *iph)
88{ 88{
89 iph->check = 0; 89 iph->check = 0;
90 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); 90 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index d3ddd8400354..ecd60733e5e2 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1081,6 +1081,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
1081 } 1081 }
1082 if (t == NULL) 1082 if (t == NULL)
1083 t = netdev_priv(dev); 1083 t = netdev_priv(dev);
1084 memset(&p, 0, sizeof(p));
1084 ip6gre_tnl_parm_to_user(&p, &t->parms); 1085 ip6gre_tnl_parm_to_user(&p, &t->parms);
1085 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1086 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1086 err = -EFAULT; 1087 err = -EFAULT;
@@ -1128,6 +1129,7 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
1128 if (t) { 1129 if (t) {
1129 err = 0; 1130 err = 0;
1130 1131
1132 memset(&p, 0, sizeof(p));
1131 ip6gre_tnl_parm_to_user(&p, &t->parms); 1133 ip6gre_tnl_parm_to_user(&p, &t->parms);
1132 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) 1134 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
1133 err = -EFAULT; 1135 err = -EFAULT;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 71167069b394..0a17ed9eaf39 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1890,6 +1890,17 @@ void tcp6_proc_exit(struct net *net)
1890} 1890}
1891#endif 1891#endif
1892 1892
1893static void tcp_v6_clear_sk(struct sock *sk, int size)
1894{
1895 struct inet_sock *inet = inet_sk(sk);
1896
1897 /* we do not want to clear pinet6 field, because of RCU lookups */
1898 sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6));
1899
1900 size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
1901 memset(&inet->pinet6 + 1, 0, size);
1902}
1903
1893struct proto tcpv6_prot = { 1904struct proto tcpv6_prot = {
1894 .name = "TCPv6", 1905 .name = "TCPv6",
1895 .owner = THIS_MODULE, 1906 .owner = THIS_MODULE,
@@ -1933,6 +1944,7 @@ struct proto tcpv6_prot = {
1933#ifdef CONFIG_MEMCG_KMEM 1944#ifdef CONFIG_MEMCG_KMEM
1934 .proto_cgroup = tcp_proto_cgroup, 1945 .proto_cgroup = tcp_proto_cgroup,
1935#endif 1946#endif
1947 .clear_sk = tcp_v6_clear_sk,
1936}; 1948};
1937 1949
1938static const struct inet6_protocol tcpv6_protocol = { 1950static const struct inet6_protocol tcpv6_protocol = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d4defdd44937..42923b14dfa6 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1432,6 +1432,17 @@ void udp6_proc_exit(struct net *net) {
1432} 1432}
1433#endif /* CONFIG_PROC_FS */ 1433#endif /* CONFIG_PROC_FS */
1434 1434
1435void udp_v6_clear_sk(struct sock *sk, int size)
1436{
1437 struct inet_sock *inet = inet_sk(sk);
1438
1439 /* we do not want to clear pinet6 field, because of RCU lookups */
1440 sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6));
1441
1442 size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
1443 memset(&inet->pinet6 + 1, 0, size);
1444}
1445
1435/* ------------------------------------------------------------------------ */ 1446/* ------------------------------------------------------------------------ */
1436 1447
1437struct proto udpv6_prot = { 1448struct proto udpv6_prot = {
@@ -1462,7 +1473,7 @@ struct proto udpv6_prot = {
1462 .compat_setsockopt = compat_udpv6_setsockopt, 1473 .compat_setsockopt = compat_udpv6_setsockopt,
1463 .compat_getsockopt = compat_udpv6_getsockopt, 1474 .compat_getsockopt = compat_udpv6_getsockopt,
1464#endif 1475#endif
1465 .clear_sk = sk_prot_clear_portaddr_nulls, 1476 .clear_sk = udp_v6_clear_sk,
1466}; 1477};
1467 1478
1468static struct inet_protosw udpv6_protosw = { 1479static struct inet_protosw udpv6_protosw = {
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index d7571046bfc4..4691ed50a928 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -31,6 +31,8 @@ extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
31extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); 31extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
32extern void udpv6_destroy_sock(struct sock *sk); 32extern void udpv6_destroy_sock(struct sock *sk);
33 33
34extern void udp_v6_clear_sk(struct sock *sk, int size);
35
34#ifdef CONFIG_PROC_FS 36#ifdef CONFIG_PROC_FS
35extern int udp6_seq_show(struct seq_file *seq, void *v); 37extern int udp6_seq_show(struct seq_file *seq, void *v);
36#endif 38#endif
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 1d08e21d9f69..dfcc4be46898 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -56,7 +56,7 @@ struct proto udplitev6_prot = {
56 .compat_setsockopt = compat_udpv6_setsockopt, 56 .compat_setsockopt = compat_udpv6_setsockopt,
57 .compat_getsockopt = compat_udpv6_getsockopt, 57 .compat_getsockopt = compat_udpv6_getsockopt,
58#endif 58#endif
59 .clear_sk = sk_prot_clear_portaddr_nulls, 59 .clear_sk = udp_v6_clear_sk,
60}; 60};
61 61
62static struct inet_protosw udplite6_protosw = { 62static struct inet_protosw udplite6_protosw = {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 4ef7bdb65440..23ed03d786c8 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -103,8 +103,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
103 dev_hold(dev); 103 dev_hold(dev);
104 104
105 xdst->u.rt6.rt6i_idev = in6_dev_get(dev); 105 xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
106 if (!xdst->u.rt6.rt6i_idev) 106 if (!xdst->u.rt6.rt6i_idev) {
107 dev_put(dev);
107 return -ENODEV; 108 return -ENODEV;
109 }
108 110
109 rt6_transfer_peer(&xdst->u.rt6, rt); 111 rt6_transfer_peer(&xdst->u.rt6, rt);
110 112