[OpenWrt-Devel] [PATCH openwrt 3/3] kernel: bridge, multicast-to-unicast: assign src after pskb_may_pull()

Linus Lüssing linus.luessing at c0d3.blue
Thu Jun 18 11:23:03 EDT 2015


A call to pskb_may_pull() might reallocate skb->data. Therefore we
should only assign the src-pointer after any potential reallocations.

Signed-off-by: Linus Lüssing <linus.luessing at c0d3.blue>
---
 .../645-bridge_multicast_to_unicast.patch          |   45 +++++++++++---------
 .../645-bridge_multicast_to_unicast.patch          |   45 +++++++++++---------
 2 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/target/linux/generic/patches-3.18/645-bridge_multicast_to_unicast.patch b/target/linux/generic/patches-3.18/645-bridge_multicast_to_unicast.patch
index e8be1fd..83f2475 100644
--- a/target/linux/generic/patches-3.18/645-bridge_multicast_to_unicast.patch
+++ b/target/linux/generic/patches-3.18/645-bridge_multicast_to_unicast.patch
@@ -100,37 +100,40 @@
  					 struct sk_buff *skb,
  					 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct igmpv3_report *ih;
  	struct igmpv3_grec *grec;
  	int i;
-@@ -1008,7 +1031,7 @@ static int br_ip4_multicast_igmp3_report
+@@ -1008,7 +1031,8 @@ static int br_ip4_multicast_igmp3_report
  			continue;
  		}
  
 -		err = br_ip4_multicast_add_group(br, port, group, vid);
++		src = eth_hdr(skb)->h_source;
 +		err = br_ip4_multicast_add_group(br, port, group, vid, src);
  		if (err)
  			break;
  	}
-@@ -1022,6 +1045,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1022,6 +1046,7 @@ static int br_ip6_multicast_mld2_report(
  					struct sk_buff *skb,
  					u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct icmp6hdr *icmp6h;
  	struct mld2_grec *grec;
  	int i;
-@@ -1070,7 +1094,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1069,8 +1094,9 @@ static int br_ip6_multicast_mld2_report(
+ 			continue;
  		}
  
++		src = eth_hdr(skb)->h_source;
  		err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
 -						 vid);
 +						 vid, src);
  		if (err)
  			break;
  	}
-@@ -1407,7 +1431,8 @@ br_multicast_leave_group(struct net_brid
+@@ -1407,7 +1433,8 @@ br_multicast_leave_group(struct net_brid
  			 struct net_bridge_port *port,
  			 struct br_ip *group,
  			 struct bridge_mcast_other_query *other_query,
@@ -140,7 +143,7 @@
  {
  	struct net_bridge_mdb_htable *mdb;
  	struct net_bridge_mdb_entry *mp;
-@@ -1457,7 +1482,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1457,7 +1484,7 @@ br_multicast_leave_group(struct net_brid
  		for (pp = &mp->ports;
  		     (p = mlock_dereference(*pp, br)) != NULL;
  		     pp = &p->next) {
@@ -149,7 +152,7 @@
  				continue;
  
  			rcu_assign_pointer(*pp, p->next);
-@@ -1491,7 +1516,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1491,7 +1518,7 @@ br_multicast_leave_group(struct net_brid
  	for (p = mlock_dereference(mp->ports, br);
  	     p != NULL;
  	     p = mlock_dereference(p->next, br)) {
@@ -158,7 +161,7 @@
  			continue;
  
  		if (!hlist_unhashed(&p->mglist) &&
-@@ -1509,8 +1534,8 @@ out:
+@@ -1509,8 +1536,8 @@ out:
  
  static void br_ip4_multicast_leave_group(struct net_bridge *br,
  					 struct net_bridge_port *port,
@@ -169,7 +172,7 @@
  {
  	struct br_ip br_group;
  	struct bridge_mcast_own_query *own_query;
-@@ -1525,14 +1550,14 @@ static void br_ip4_multicast_leave_group
+@@ -1525,14 +1552,14 @@ static void br_ip4_multicast_leave_group
  	br_group.vid = vid;
  
  	br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query,
@@ -186,7 +189,7 @@
  {
  	struct br_ip br_group;
  	struct bridge_mcast_own_query *own_query;
-@@ -1547,7 +1572,7 @@ static void br_ip6_multicast_leave_group
+@@ -1547,7 +1574,7 @@ static void br_ip6_multicast_leave_group
  	br_group.vid = vid;
  
  	br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query,
@@ -195,55 +198,59 @@
  }
  #endif
  
-@@ -1556,6 +1581,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1556,6 +1583,7 @@ static int br_multicast_ipv4_rcv(struct
  				 struct sk_buff *skb,
  				 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct sk_buff *skb2 = skb;
  	const struct iphdr *iph;
  	struct igmphdr *ih;
-@@ -1629,7 +1655,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1629,7 +1657,8 @@ static int br_multicast_ipv4_rcv(struct
  	case IGMP_HOST_MEMBERSHIP_REPORT:
  	case IGMPV2_HOST_MEMBERSHIP_REPORT:
  		BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 -		err = br_ip4_multicast_add_group(br, port, ih->group, vid);
++		src = eth_hdr(skb)->h_source;
 +		err = br_ip4_multicast_add_group(br, port, ih->group, vid, src);
  		break;
  	case IGMPV3_HOST_MEMBERSHIP_REPORT:
  		err = br_ip4_multicast_igmp3_report(br, port, skb2, vid);
-@@ -1638,7 +1664,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1638,7 +1667,8 @@ static int br_multicast_ipv4_rcv(struct
  		err = br_ip4_multicast_query(br, port, skb2, vid);
  		break;
  	case IGMP_HOST_LEAVE_MESSAGE:
 -		br_ip4_multicast_leave_group(br, port, ih->group, vid);
++		src = eth_hdr(skb)->h_source;
 +		br_ip4_multicast_leave_group(br, port, ih->group, vid, src);
  		break;
  	}
  
-@@ -1656,6 +1682,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1656,6 +1686,7 @@ static int br_multicast_ipv6_rcv(struct
  				 struct sk_buff *skb,
  				 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct sk_buff *skb2;
  	const struct ipv6hdr *ip6h;
  	u8 icmp6_type;
-@@ -1765,7 +1792,8 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1765,7 +1796,9 @@ static int br_multicast_ipv6_rcv(struct
  		}
  		mld = (struct mld_msg *)skb_transport_header(skb2);
  		BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 -		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid);
++		src = eth_hdr(skb)->h_source;
 +		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid,
 +						 src);
  		break;
  	    }
  	case ICMPV6_MLD2_REPORT:
-@@ -1782,7 +1810,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1782,7 +1815,8 @@ static int br_multicast_ipv6_rcv(struct
  			goto out;
  		}
  		mld = (struct mld_msg *)skb_transport_header(skb2);
 -		br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid);
++		src = eth_hdr(skb)->h_source;
 +		br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src);
  	    }
  	}
diff --git a/target/linux/generic/patches-4.0/645-bridge_multicast_to_unicast.patch b/target/linux/generic/patches-4.0/645-bridge_multicast_to_unicast.patch
index f3d7a16..2fd2a34 100644
--- a/target/linux/generic/patches-4.0/645-bridge_multicast_to_unicast.patch
+++ b/target/linux/generic/patches-4.0/645-bridge_multicast_to_unicast.patch
@@ -110,37 +110,40 @@
  					 struct sk_buff *skb,
  					 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct igmpv3_report *ih;
  	struct igmpv3_grec *grec;
  	int i;
-@@ -1008,7 +1031,7 @@ static int br_ip4_multicast_igmp3_report
+@@ -1008,7 +1031,8 @@ static int br_ip4_multicast_igmp3_report
  			continue;
  		}
  
 -		err = br_ip4_multicast_add_group(br, port, group, vid);
++		src = eth_hdr(skb)->h_source;
 +		err = br_ip4_multicast_add_group(br, port, group, vid, src);
  		if (err)
  			break;
  	}
-@@ -1022,6 +1045,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1022,6 +1046,7 @@ static int br_ip6_multicast_mld2_report(
  					struct sk_buff *skb,
  					u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct icmp6hdr *icmp6h;
  	struct mld2_grec *grec;
  	int i;
-@@ -1070,7 +1094,7 @@ static int br_ip6_multicast_mld2_report(
+@@ -1069,8 +1094,9 @@ static int br_ip6_multicast_mld2_report(
+ 			continue;
  		}
  
++		src = eth_hdr(skb)->h_source;
  		err = br_ip6_multicast_add_group(br, port, &grec->grec_mca,
 -						 vid);
 +						 vid, src);
  		if (!err)
  			break;
  	}
-@@ -1407,7 +1431,8 @@ br_multicast_leave_group(struct net_brid
+@@ -1407,7 +1433,8 @@ br_multicast_leave_group(struct net_brid
  			 struct net_bridge_port *port,
  			 struct br_ip *group,
  			 struct bridge_mcast_other_query *other_query,
@@ -150,7 +153,7 @@
  {
  	struct net_bridge_mdb_htable *mdb;
  	struct net_bridge_mdb_entry *mp;
-@@ -1457,7 +1482,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1457,7 +1484,7 @@ br_multicast_leave_group(struct net_brid
  		for (pp = &mp->ports;
  		     (p = mlock_dereference(*pp, br)) != NULL;
  		     pp = &p->next) {
@@ -159,7 +162,7 @@
  				continue;
  
  			rcu_assign_pointer(*pp, p->next);
-@@ -1491,7 +1516,7 @@ br_multicast_leave_group(struct net_brid
+@@ -1491,7 +1518,7 @@ br_multicast_leave_group(struct net_brid
  	for (p = mlock_dereference(mp->ports, br);
  	     p != NULL;
  	     p = mlock_dereference(p->next, br)) {
@@ -168,7 +171,7 @@
  			continue;
  
  		if (!hlist_unhashed(&p->mglist) &&
-@@ -1509,8 +1534,8 @@ out:
+@@ -1509,8 +1536,8 @@ out:
  
  static void br_ip4_multicast_leave_group(struct net_bridge *br,
  					 struct net_bridge_port *port,
@@ -179,7 +182,7 @@
  {
  	struct br_ip br_group;
  	struct bridge_mcast_own_query *own_query;
-@@ -1525,14 +1550,14 @@ static void br_ip4_multicast_leave_group
+@@ -1525,14 +1552,14 @@ static void br_ip4_multicast_leave_group
  	br_group.vid = vid;
  
  	br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query,
@@ -196,7 +199,7 @@
  {
  	struct br_ip br_group;
  	struct bridge_mcast_own_query *own_query;
-@@ -1547,7 +1572,7 @@ static void br_ip6_multicast_leave_group
+@@ -1547,7 +1574,7 @@ static void br_ip6_multicast_leave_group
  	br_group.vid = vid;
  
  	br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query,
@@ -205,55 +208,59 @@
  }
  #endif
  
-@@ -1556,6 +1581,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1556,6 +1583,7 @@ static int br_multicast_ipv4_rcv(struct
  				 struct sk_buff *skb,
  				 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct sk_buff *skb2 = skb;
  	const struct iphdr *iph;
  	struct igmphdr *ih;
-@@ -1629,7 +1655,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1629,7 +1657,8 @@ static int br_multicast_ipv4_rcv(struct
  	case IGMP_HOST_MEMBERSHIP_REPORT:
  	case IGMPV2_HOST_MEMBERSHIP_REPORT:
  		BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 -		err = br_ip4_multicast_add_group(br, port, ih->group, vid);
++       		src = eth_hdr(skb)->h_source;
 +		err = br_ip4_multicast_add_group(br, port, ih->group, vid, src);
  		break;
  	case IGMPV3_HOST_MEMBERSHIP_REPORT:
  		err = br_ip4_multicast_igmp3_report(br, port, skb2, vid);
-@@ -1638,7 +1664,7 @@ static int br_multicast_ipv4_rcv(struct
+@@ -1638,7 +1667,8 @@ static int br_multicast_ipv4_rcv(struct
  		err = br_ip4_multicast_query(br, port, skb2, vid);
  		break;
  	case IGMP_HOST_LEAVE_MESSAGE:
 -		br_ip4_multicast_leave_group(br, port, ih->group, vid);
++       		src = eth_hdr(skb)->h_source;
 +		br_ip4_multicast_leave_group(br, port, ih->group, vid, src);
  		break;
  	}
  
-@@ -1656,6 +1682,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1656,6 +1686,7 @@ static int br_multicast_ipv6_rcv(struct
  				 struct sk_buff *skb,
  				 u16 vid)
  {
-+	const unsigned char *src = eth_hdr(skb)->h_source;
++	unsigned char *src;
  	struct sk_buff *skb2;
  	const struct ipv6hdr *ip6h;
  	u8 icmp6_type;
-@@ -1765,7 +1792,8 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1765,7 +1796,9 @@ static int br_multicast_ipv6_rcv(struct
  		}
  		mld = (struct mld_msg *)skb_transport_header(skb2);
  		BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 -		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid);
++		src = eth_hdr(skb)->h_source;
 +		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca, vid,
 +						 src);
  		break;
  	    }
  	case ICMPV6_MLD2_REPORT:
-@@ -1782,7 +1810,7 @@ static int br_multicast_ipv6_rcv(struct
+@@ -1782,7 +1815,8 @@ static int br_multicast_ipv6_rcv(struct
  			goto out;
  		}
  		mld = (struct mld_msg *)skb_transport_header(skb2);
 -		br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid);
++		src = eth_hdr(skb)->h_source;
 +		br_ip6_multicast_leave_group(br, port, &mld->mld_mca, vid, src);
  	    }
  	}
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list