aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 16:20:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 16:20:02 -0500
commit8d9ea7172edd2e52da26b9485b4c97969a0d2648 (patch)
treef3359dbcecca68963961a3840b9b6221554c7642
parentf6e858a00af788bab0fd4c0b7f5cd788000edc18 (diff)
parenteca2a43bb0d2c6ebd528be6acb30a88435abe307 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "A pile of fixes in response to yesterday's big merge. The SCTP HMAC thing hasn't been addressed yet, I'll take care of that myself if Neil and Vlad don't show signs of life by tomorrow. 1) Use after free of SKB in tuntap code. Fix by Eric Dumazet, reported by Dave Jones. 2) NFC LLCP code emits annoying kernel log message, triggerable by the user. From Dave Jones. 3) Fix several endianness bugs noticed by sparse in the bridging code, from Stephen Hemminger. 4) Ipv6 NDISC code doesn't take padding into account properly, fix from YOSHIFUJI Hideaki. 5) Add missing docs to ethtool_flow_ext struct, from Yan Burman." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: bridge: fix icmpv6 endian bug and other sparse warnings net: ethool: Document struct ethtool_flow_ext ndisc: Fix padding error in link-layer address option. tuntap: dont use skb after netif_rx_ni(skb) nfc: remove noisy message from llcp_sock_sendmsg
-rw-r--r--drivers/net/tun.c7
-rw-r--r--include/uapi/linux/ethtool.h16
-rw-r--r--net/bridge/br_multicast.c10
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/nfc/llcp/sock.c4
5 files changed, 25 insertions, 14 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2ac2164a1e39..40b426edc9e6 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -297,13 +297,12 @@ static void tun_flow_cleanup(unsigned long data)
297 spin_unlock_bh(&tun->lock); 297 spin_unlock_bh(&tun->lock);
298} 298}
299 299
300static void tun_flow_update(struct tun_struct *tun, struct sk_buff *skb, 300static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
301 u16 queue_index) 301 u16 queue_index)
302{ 302{
303 struct hlist_head *head; 303 struct hlist_head *head;
304 struct tun_flow_entry *e; 304 struct tun_flow_entry *e;
305 unsigned long delay = tun->ageing_time; 305 unsigned long delay = tun->ageing_time;
306 u32 rxhash = skb_get_rxhash(skb);
307 306
308 if (!rxhash) 307 if (!rxhash)
309 return; 308 return;
@@ -1010,6 +1009,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1010 int copylen; 1009 int copylen;
1011 bool zerocopy = false; 1010 bool zerocopy = false;
1012 int err; 1011 int err;
1012 u32 rxhash;
1013 1013
1014 if (!(tun->flags & TUN_NO_PI)) { 1014 if (!(tun->flags & TUN_NO_PI)) {
1015 if ((len -= sizeof(pi)) > total_len) 1015 if ((len -= sizeof(pi)) > total_len)
@@ -1162,12 +1162,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1162 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; 1162 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
1163 } 1163 }
1164 1164
1165 rxhash = skb_get_rxhash(skb);
1165 netif_rx_ni(skb); 1166 netif_rx_ni(skb);
1166 1167
1167 tun->dev->stats.rx_packets++; 1168 tun->dev->stats.rx_packets++;
1168 tun->dev->stats.rx_bytes += len; 1169 tun->dev->stats.rx_bytes += len;
1169 1170
1170 tun_flow_update(tun, skb, tfile->queue_index); 1171 tun_flow_update(tun, rxhash, tfile->queue_index);
1171 return total_len; 1172 return total_len;
1172} 1173}
1173 1174
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index be8c41e2dc15..0c9b44871df0 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -503,9 +503,20 @@ union ethtool_flow_union {
503 __u8 hdata[52]; 503 __u8 hdata[52];
504}; 504};
505 505
506/**
507 * struct ethtool_flow_ext - additional RX flow fields
508 * @h_dest: destination MAC address
509 * @vlan_etype: VLAN EtherType
510 * @vlan_tci: VLAN tag control information
511 * @data: user defined data
512 *
513 * Note, @vlan_etype, @vlan_tci, and @data are only valid if %FLOW_EXT
514 * is set in &struct ethtool_rx_flow_spec @flow_type.
515 * @h_dest is valid if %FLOW_MAC_EXT is set.
516 */
506struct ethtool_flow_ext { 517struct ethtool_flow_ext {
507 __u8 padding[2]; 518 __u8 padding[2];
508 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ 519 unsigned char h_dest[ETH_ALEN];
509 __be16 vlan_etype; 520 __be16 vlan_etype;
510 __be16 vlan_tci; 521 __be16 vlan_tci;
511 __be32 data[2]; 522 __be32 data[2];
@@ -519,7 +530,8 @@ struct ethtool_flow_ext {
519 * @m_u: Masks for flow field bits to be matched 530 * @m_u: Masks for flow field bits to be matched
520 * @m_ext: Masks for additional field bits to be matched 531 * @m_ext: Masks for additional field bits to be matched
521 * Note, all additional fields must be ignored unless @flow_type 532 * Note, all additional fields must be ignored unless @flow_type
522 * includes the %FLOW_EXT flag. 533 * includes the %FLOW_EXT or %FLOW_MAC_EXT flag
534 * (see &struct ethtool_flow_ext description).
523 * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC 535 * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
524 * if packets should be discarded 536 * if packets should be discarded
525 * @location: Location of rule in the table. Locations must be 537 * @location: Location of rule in the table. Locations must be
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 977c3ee02e65..1093c89095d8 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -622,7 +622,7 @@ out:
622struct net_bridge_port_group *br_multicast_new_port_group( 622struct net_bridge_port_group *br_multicast_new_port_group(
623 struct net_bridge_port *port, 623 struct net_bridge_port *port,
624 struct br_ip *group, 624 struct br_ip *group,
625 struct net_bridge_port_group *next) 625 struct net_bridge_port_group __rcu *next)
626{ 626{
627 struct net_bridge_port_group *p; 627 struct net_bridge_port_group *p;
628 628
@@ -632,7 +632,7 @@ struct net_bridge_port_group *br_multicast_new_port_group(
632 632
633 p->addr = *group; 633 p->addr = *group;
634 p->port = port; 634 p->port = port;
635 p->next = next; 635 rcu_assign_pointer(p->next, next);
636 hlist_add_head(&p->mglist, &port->mglist); 636 hlist_add_head(&p->mglist, &port->mglist);
637 setup_timer(&p->timer, br_multicast_port_group_expired, 637 setup_timer(&p->timer, br_multicast_port_group_expired,
638 (unsigned long)p); 638 (unsigned long)p);
@@ -1138,7 +1138,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1138 struct sk_buff *skb) 1138 struct sk_buff *skb)
1139{ 1139{
1140 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 1140 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
1141 struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); 1141 struct mld_msg *mld;
1142 struct net_bridge_mdb_entry *mp; 1142 struct net_bridge_mdb_entry *mp;
1143 struct mld2_query *mld2q; 1143 struct mld2_query *mld2q;
1144 struct net_bridge_port_group *p; 1144 struct net_bridge_port_group *p;
@@ -1165,6 +1165,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1165 if (max_delay) 1165 if (max_delay)
1166 group = &mld->mld_mca; 1166 group = &mld->mld_mca;
1167 } else if (skb->len >= sizeof(*mld2q)) { 1167 } else if (skb->len >= sizeof(*mld2q)) {
1168 u16 mrc;
1168 if (!pskb_may_pull(skb, sizeof(*mld2q))) { 1169 if (!pskb_may_pull(skb, sizeof(*mld2q))) {
1169 err = -EINVAL; 1170 err = -EINVAL;
1170 goto out; 1171 goto out;
@@ -1172,7 +1173,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1172 mld2q = (struct mld2_query *)icmp6_hdr(skb); 1173 mld2q = (struct mld2_query *)icmp6_hdr(skb);
1173 if (!mld2q->mld2q_nsrcs) 1174 if (!mld2q->mld2q_nsrcs)
1174 group = &mld2q->mld2q_mca; 1175 group = &mld2q->mld2q_mca;
1175 max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1; 1176 mrc = ntohs(mld2q->mld2q_mrc);
1177 max_delay = mrc ? MLDV2_MRC(mrc) : 1;
1176 } 1178 }
1177 1179
1178 if (!group) 1180 if (!group)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 4c02e6ab96e7..f2a007b7bde3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -151,8 +151,8 @@ static inline int ndisc_opt_addr_space(struct net_device *dev)
151static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len, 151static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
152 unsigned short addr_type) 152 unsigned short addr_type)
153{ 153{
154 int space = NDISC_OPT_SPACE(data_len);
155 int pad = ndisc_addr_option_pad(addr_type); 154 int pad = ndisc_addr_option_pad(addr_type);
155 int space = NDISC_OPT_SPACE(data_len + pad);
156 156
157 opt[0] = type; 157 opt[0] = type;
158 opt[1] = space>>3; 158 opt[1] = space>>3;
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 0fa1e92ceac8..fea22eb41b82 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -614,10 +614,6 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
614 614
615 if (msg->msg_namelen < sizeof(*addr)) { 615 if (msg->msg_namelen < sizeof(*addr)) {
616 release_sock(sk); 616 release_sock(sk);
617
618 pr_err("Invalid socket address length %d\n",
619 msg->msg_namelen);
620
621 return -EINVAL; 617 return -EINVAL;
622 } 618 }
623 619