All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets
@ 2013-05-29  5:27 Simon Horman
  2013-05-29  5:27 ` [PATCH 1/7] isdn: Correct comparison of skb->tail and skb-transport_header Simon Horman
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

Many apologies for not having the foresight to spot these problems earlier.

These problems relate to comparisons between integer offsets and pointers
that occur when NET_SKBUFF_DATA_USES_OFFSET is not set

These are regressions caused by "net: Use 16bits for *_headers fields of
struct skbuff".

Simon Horman (7):
  isdn: Correct comparison of skb->tail and skb-transport_header
  cxgb3: Correct comparisons and calculations using skb->tail and
    skb-transport_header
  net: Correct comparisons and calculations using skb->tail and
    skb-transport_header
  ipv6: Correct comparisons and calculations using skb->tail and
    skb-transport_header
  ipv4: Correct comparisons and calculations using skb->tail and
    skb-transport_header
  sctp: Correct access to skb->{network,transport}_header
  net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail

 drivers/isdn/i4l/isdn_net.c              |    2 +-
 drivers/net/ethernet/chelsio/cxgb3/sge.c |   11 +++++------
 include/linux/skbuff.h                   |    9 +++++++++
 include/net/inet_ecn.h                   |    6 ++++--
 net/core/dev.c                           |    4 ++--
 net/core/netpoll.c                       |    9 ++++++++-
 net/core/pktgen.c                        |   16 ++++++++++++++--
 net/ipv4/icmp.c                          |    3 ++-
 net/ipv4/igmp.c                          |    2 +-
 net/ipv4/ipmr.c                          |    8 +++++++-
 net/ipv4/tcp.c                           |    3 ++-
 net/ipv6/exthdrs_core.c                  |    2 +-
 net/ipv6/icmp.c                          |    2 +-
 net/ipv6/mcast.c                         |    5 +++--
 net/ipv6/mip6.c                          |    6 ++++--
 net/ipv6/ndisc.c                         |    9 +++++----
 net/ipv6/output_core.c                   |    3 ++-
 net/ipv6/raw.c                           |    3 ++-
 net/ipv6/route.c                         |    2 +-
 net/sctp/input.c                         |    2 +-
 net/sctp/ipv6.c                          |    2 +-
 21 files changed, 76 insertions(+), 33 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/7] isdn: Correct comparison of skb->tail and skb-transport_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:27 ` [PATCH 2/7] cxgb3: Correct comparisons and calculations using " Simon Horman
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that the comparison is always between pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 drivers/isdn/i4l/isdn_net.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 88d657d..8b98d53 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -885,7 +885,7 @@ isdn_net_log_skb(struct sk_buff *skb, isdn_net_local *lp)
 
 	addinfo[0] = '\0';
 	/* This check stolen from 2.1.72 dev_queue_xmit_nit() */
-	if (p < skb->data || skb->network_header >= skb->tail) {
+	if (p < skb->data || skb_network_header(skb) >= skb_tail_pointer(skb)) {
 		/* fall back to old isdn_net_log_packet method() */
 		char *buf = skb->data;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/7] cxgb3: Correct comparisons and calculations using skb->tail and skb-transport_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
  2013-05-29  5:27 ` [PATCH 1/7] isdn: Correct comparison of skb->tail and skb-transport_header Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:27 ` [PATCH 3/7] net: " Simon Horman
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 drivers/net/ethernet/chelsio/cxgb3/sge.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb3/sge.c b/drivers/net/ethernet/chelsio/cxgb3/sge.c
index 2fd773e..46d1efc 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c
@@ -1584,9 +1584,8 @@ static void deferred_unmap_destructor(struct sk_buff *skb)
 	p = dui->addr;
 
 	if (skb->tail - skb->transport_header)
-		pci_unmap_single(dui->pdev, *p++,
-				 skb->tail - skb->transport_header,
-				 PCI_DMA_TODEVICE);
+		pci_unmap_single(dui->pdev, *p++, skb_tail_pointer(skb) -
+				 skb_transport_header(skb), PCI_DMA_TODEVICE);
 
 	si = skb_shinfo(skb);
 	for (i = 0; i < si->nr_frags; i++)
@@ -1647,8 +1646,8 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
 	flits = skb_transport_offset(skb) / 8;
 	sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
 	sgl_flits = write_sgl(skb, sgp, skb_transport_header(skb),
-			     skb->tail - skb->transport_header,
-			     addr);
+			     skb_tail_pointer(skb) -
+			     skb_transport_header(skb), addr);
 	if (need_skb_unmap()) {
 		setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
 		skb->destructor = deferred_unmap_destructor;
@@ -1674,7 +1673,7 @@ static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
 
 	flits = skb_transport_offset(skb) / 8;	/* headers */
 	cnt = skb_shinfo(skb)->nr_frags;
-	if (skb->tail != skb->transport_header)
+	if (skb_tail_pointer(skb) != skb_transport_header(skb))
 		cnt++;
 	return flits_to_desc(flits + sgl_len(cnt));
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/7] net: Correct comparisons and calculations using skb->tail and skb-transport_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
  2013-05-29  5:27 ` [PATCH 1/7] isdn: Correct comparison of skb->tail and skb-transport_header Simon Horman
  2013-05-29  5:27 ` [PATCH 2/7] cxgb3: Correct comparisons and calculations using " Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:27 ` [PATCH 4/7] ipv6: " Simon Horman
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 include/net/inet_ecn.h |    6 ++++--
 net/core/dev.c         |    4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index aab7375..3bd2279 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -134,12 +134,14 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb)
 {
 	switch (skb->protocol) {
 	case cpu_to_be16(ETH_P_IP):
-		if (skb->network_header + sizeof(struct iphdr) <= skb->tail)
+		if (skb_network_header(skb) + sizeof(struct iphdr) <=
+		    skb_tail_pointer(skb))
 			return IP_ECN_set_ce(ip_hdr(skb));
 		break;
 
 	case cpu_to_be16(ETH_P_IPV6):
-		if (skb->network_header + sizeof(struct ipv6hdr) <= skb->tail)
+		if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
+		    skb_tail_pointer(skb))
 			return IP6_ECN_set_ce(ipv6_hdr(skb));
 		break;
 	}
diff --git a/net/core/dev.c b/net/core/dev.c
index 6eb621c..f5c9aa3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1730,7 +1730,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 			skb_reset_mac_header(skb2);
 
 			if (skb_network_header(skb2) < skb2->data ||
-			    skb2->network_header > skb2->tail) {
+			    skb_network_header(skb2) > skb_tail_pointer(skb2)) {
 				net_crit_ratelimited("protocol %04x is buggy, dev %s\n",
 						     ntohs(skb2->protocol),
 						     dev->name);
@@ -3898,7 +3898,7 @@ static void skb_gro_reset_offset(struct sk_buff *skb)
 	NAPI_GRO_CB(skb)->frag0 = NULL;
 	NAPI_GRO_CB(skb)->frag0_len = 0;
 
-	if (skb->mac_header == skb->tail &&
+	if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
 	    pinfo->nr_frags &&
 	    !PageHighMem(skb_frag_page(frag0))) {
 		NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/7] ipv6: Correct comparisons and calculations using skb->tail and skb-transport_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
                   ` (2 preceding siblings ...)
  2013-05-29  5:27 ` [PATCH 3/7] net: " Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:27 ` [PATCH 5/7] ipv4: " Simon Horman
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 net/ipv6/exthdrs_core.c |    2 +-
 net/ipv6/icmp.c         |    2 +-
 net/ipv6/mcast.c        |    5 +++--
 net/ipv6/mip6.c         |    6 ++++--
 net/ipv6/ndisc.c        |    9 +++++----
 net/ipv6/output_core.c  |    3 ++-
 net/ipv6/raw.c          |    3 ++-
 net/ipv6/route.c        |    2 +-
 8 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index c5e83fa..140748d 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -115,7 +115,7 @@ EXPORT_SYMBOL(ipv6_skip_exthdr);
 int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
 {
 	const unsigned char *nh = skb_network_header(skb);
-	int packet_len = skb->tail - skb->network_header;
+	int packet_len = skb_tail_pointer(skb) - skb_network_header(skb);
 	struct ipv6_opt_hdr *hdr;
 	int len;
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 1d2902e..4b4890b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -399,7 +399,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 	int err = 0;
 
 	if ((u8 *)hdr < skb->head ||
-	    (skb->network_header + sizeof(*hdr)) > skb->tail)
+	    (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
 		return;
 
 	/*
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index bfa6cc3..72c8bfe 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1409,8 +1409,9 @@ static void mld_sendpack(struct sk_buff *skb)
 	idev = __in6_dev_get(skb->dev);
 	IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
-	payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
-	mldlen = skb->tail - skb->transport_header;
+	payload_len = (skb_tail_pointer(skb) - skb_network_header(skb)) -
+		sizeof(*pip6);
+	mldlen = skb_tail_pointer(skb) - skb_transport_header(skb);
 	pip6->payload_len = htons(payload_len);
 
 	pmr->mld2r_cksum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 0f9bdc5..9ac01dc 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -268,7 +268,8 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
 	struct ipv6_opt_hdr *exthdr =
 				   (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
 	const unsigned char *nh = skb_network_header(skb);
-	unsigned int packet_len = skb->tail - skb->network_header;
+	unsigned int packet_len = skb_tail_pointer(skb) -
+		skb_network_header(skb);
 	int found_rhdr = 0;
 
 	*nexthdr = &ipv6_hdr(skb)->nexthdr;
@@ -404,7 +405,8 @@ static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
 	struct ipv6_opt_hdr *exthdr =
 				   (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
 	const unsigned char *nh = skb_network_header(skb);
-	unsigned int packet_len = skb->tail - skb->network_header;
+	unsigned int packet_len = skb_tail_pointer(skb) -
+		skb_network_header(skb);
 	int found_rhdr = 0;
 
 	*nexthdr = &ipv6_hdr(skb)->nexthdr;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a096269..781dd3c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -693,7 +693,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
 	const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
 	const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
 	u8 *lladdr = NULL;
-	u32 ndoptlen = skb->tail - (skb->transport_header +
+	u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
 				    offsetof(struct nd_msg, opt));
 	struct ndisc_options ndopts;
 	struct net_device *dev = skb->dev;
@@ -853,7 +853,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
 	const struct in6_addr *saddr = &ipv6_hdr(skb)->saddr;
 	const struct in6_addr *daddr = &ipv6_hdr(skb)->daddr;
 	u8 *lladdr = NULL;
-	u32 ndoptlen = skb->tail - (skb->transport_header +
+	u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
 				    offsetof(struct nd_msg, opt));
 	struct ndisc_options ndopts;
 	struct net_device *dev = skb->dev;
@@ -1069,7 +1069,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 
 	__u8 * opt = (__u8 *)(ra_msg + 1);
 
-	optlen = (skb->tail - skb->transport_header) - sizeof(struct ra_msg);
+	optlen = (skb_tail_pointer(skb) - skb_transport_header(skb)) -
+		sizeof(struct ra_msg);
 
 	if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
 		ND_PRINTK(2, warn, "RA: source address is not link-local\n");
@@ -1346,7 +1347,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 	u8 *hdr;
 	struct ndisc_options ndopts;
 	struct rd_msg *msg = (struct rd_msg *)skb_transport_header(skb);
-	u32 ndoptlen = skb->tail - (skb->transport_header +
+	u32 ndoptlen = skb_tail_pointer(skb) - (skb_transport_header(skb) +
 				    offsetof(struct rd_msg, opt));
 
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index c2e73e6..ab92a36 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -40,7 +40,8 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 	u16 offset = sizeof(struct ipv6hdr);
 	struct ipv6_opt_hdr *exthdr =
 				(struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
-	unsigned int packet_len = skb->tail - skb->network_header;
+	unsigned int packet_len = skb_tail_pointer(skb) -
+		skb_network_header(skb);
 	int found_rhdr = 0;
 	*nexthdr = &ipv6_hdr(skb)->nexthdr;
 
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index eedff8c..4f8886a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1132,7 +1132,8 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
 		spin_lock_bh(&sk->sk_receive_queue.lock);
 		skb = skb_peek(&sk->sk_receive_queue);
 		if (skb != NULL)
-			amount = skb->tail - skb->transport_header;
+			amount = skb_tail_pointer(skb) -
+				skb_transport_header(skb);
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
 		return put_user(amount, (int __user *)arg);
 	}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 194c3cd..2b87418 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1649,7 +1649,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
 	int optlen, on_link;
 	u8 *lladdr;
 
-	optlen = skb->tail - skb->transport_header;
+	optlen = skb_tail_pointer(skb) - skb_transport_header(skb);
 	optlen -= sizeof(*msg);
 
 	if (optlen < 0) {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/7] ipv4: Correct comparisons and calculations using skb->tail and skb-transport_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
                   ` (3 preceding siblings ...)
  2013-05-29  5:27 ` [PATCH 4/7] ipv6: " Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:27 ` [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header Simon Horman
  2013-05-29  5:27 ` [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail Simon Horman
  6 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer whereas skb->transport_header
will be an offset from head. This is corrected by using wrappers that
ensure that comparisons and calculations are always made using pointers.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 net/ipv4/icmp.c |    3 ++-
 net/ipv4/igmp.c |    2 +-
 net/ipv4/tcp.c  |    3 ++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 562efd9..5d0d379 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -503,7 +503,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 	iph = ip_hdr(skb_in);
 
 	if ((u8 *)iph < skb_in->head ||
-	    (skb_in->network_header + sizeof(*iph)) > skb_in->tail)
+	    (skb_network_header(skb_in) + sizeof(*iph)) >
+	    skb_tail_pointer(skb_in))
 		goto out;
 
 	/*
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index d8c2327..450f625 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -363,7 +363,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
 static int igmpv3_sendpack(struct sk_buff *skb)
 {
 	struct igmphdr *pig = igmp_hdr(skb);
-	const int igmplen = skb->tail - skb->transport_header;
+	const int igmplen = skb_tail_pointer(skb) - skb_transport_header(skb);
 
 	pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
 
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ba4186e..1f58594 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2989,7 +2989,8 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
 		swap(gso_skb->truesize, skb->truesize);
 	}
 
-	delta = htonl(oldlen + (skb->tail - skb->transport_header) +
+	delta = htonl(oldlen + (skb_tail_pointer(skb) -
+				skb_transport_header(skb)) +
 		      skb->data_len);
 	th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
 				(__force u32)delta));
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
                   ` (4 preceding siblings ...)
  2013-05-29  5:27 ` [PATCH 5/7] ipv4: " Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29 19:31   ` Ben Hutchings
  2013-05-29  5:27 ` [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail Simon Horman
  6 siblings, 1 reply; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case sk_buff_data_t will be a pointer, however,
skb->{network,transport}_header is now __u16.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 net/sctp/input.c |    2 +-
 net/sctp/ipv6.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/sctp/input.c b/net/sctp/input.c
index 4b2c831..e328fe8 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -589,7 +589,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
 	struct sctp_association *asoc = NULL;
 	struct sctp_transport *transport;
 	struct inet_sock *inet;
-	sk_buff_data_t saveip, savesctp;
+	__be16 saveip, savesctp;
 	int err;
 	struct net *net = dev_net(skb->dev);
 
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 391a245..8ee553b 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -153,7 +153,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
 	struct ipv6_pinfo *np;
-	sk_buff_data_t saveip, savesctp;
+	__be16 saveip, savesctp;
 	int err;
 	struct net *net = dev_net(skb->dev);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail
  2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
                   ` (5 preceding siblings ...)
  2013-05-29  5:27 ` [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header Simon Horman
@ 2013-05-29  5:27 ` Simon Horman
  2013-05-29  5:35   ` Eric Dumazet
  6 siblings, 1 reply; 13+ messages in thread
From: Simon Horman @ 2013-05-29  5:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Simon Horman

This corrects an regression introduced by "net: Use 16bits for *_headers
fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
that case skb->tail will be a pointer however skb->network_header is now
an offset.

This patch corrects the problem by adding a wrapper to return skb tail as
an offset regardless of the value of NET_SKBUFF_DATA_USES_OFFSET. It seems
that skb->tail that this offset may be more than 64k and some care has been
taken to treat such cases as an error.

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 include/linux/skbuff.h |    9 +++++++++
 net/core/netpoll.c     |    9 ++++++++-
 net/core/pktgen.c      |   16 ++++++++++++++--
 net/ipv4/ipmr.c        |    8 +++++++-
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8f2b830..26ed287 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1391,6 +1391,11 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
 	skb_reset_tail_pointer(skb);
 	skb->tail += offset;
 }
+
+static inline __u64 skb_tail_offset(const struct sk_buff *skb)
+{
+	return skb->tail;
+}
 #else /* NET_SKBUFF_DATA_USES_OFFSET */
 static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
 {
@@ -1407,6 +1412,10 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
 	skb->tail = skb->data + offset;
 }
 
+static inline __u64 skb_tail_offset(const struct sk_buff *skb)
+{
+	return skb->tail - skb->head;
+}
 #endif /* NET_SKBUFF_DATA_USES_OFFSET */
 
 /*
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 37deedd..d4da003 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -676,6 +676,8 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
 		spin_lock_irqsave(&npinfo->rx_lock, flags);
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
+			__u64 tail_offset;
+
 			if (!ipv6_addr_equal(daddr, &np->local_ip.in6))
 				continue;
 
@@ -700,7 +702,12 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 			hdr->saddr = *saddr;
 			hdr->daddr = *daddr;
 
-			send_skb->transport_header = send_skb->tail;
+			tail_offset = skb_tail_offset(skb);
+			if (tail_offset > 0xffff) {
+				kfree_skb(send_skb);
+				continue;
+			}
+			skb_set_network_header(send_skb, tail_offset);
 			skb_put(send_skb, size);
 
 			icmp6h = (struct icmp6hdr *)skb_transport_header(skb);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 795498f..f2923ae 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2642,6 +2642,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 	__be16 *svlan_tci = NULL;                /* Encapsulates priority and SVLAN ID */
 	__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
 	u16 queue_map;
+	__u64 tail_offset;
 
 	if (pkt_dev->nr_labels)
 		protocol = htons(ETH_P_MPLS_UC);
@@ -2708,7 +2709,12 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 		*vlan_encapsulated_proto = htons(ETH_P_IP);
 	}
 
-	skb->network_header = skb->tail;
+	tail_offset = skb_tail_offset(skb);
+	if (tail_offset > 0xffff) {
+		kfree_skb(skb);
+		return NULL;
+	}
+	skb_set_network_header(skb, tail_offset);
 	skb->transport_header = skb->network_header + sizeof(struct iphdr);
 	skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
 	skb_set_queue_mapping(skb, queue_map);
@@ -2775,6 +2781,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 	__be16 *svlan_tci = NULL;                /* Encapsulates priority and SVLAN ID */
 	__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
 	u16 queue_map;
+	__u64 tail_offset;
 
 	if (pkt_dev->nr_labels)
 		protocol = htons(ETH_P_MPLS_UC);
@@ -2822,7 +2829,12 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 		*vlan_encapsulated_proto = htons(ETH_P_IPV6);
 	}
 
-	skb->network_header = skb->tail;
+	tail_offset = skb_tail_offset(skb);
+	if (tail_offset > 0xffff) {
+		kfree_skb(skb);
+		return NULL;
+	}
+	skb_set_network_header(skb, tail_offset);
 	skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
 	skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
 	skb_set_queue_mapping(skb, queue_map);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index f975399..d5b8b4b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -945,6 +945,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
 	struct igmpmsg *msg;
 	struct sock *mroute_sk;
 	int ret;
+	__be64 tail_offset;
 
 #ifdef CONFIG_IP_PIMSM
 	if (assert == IGMPMSG_WHOLEPKT)
@@ -980,7 +981,12 @@ static int ipmr_cache_report(struct mr_table *mrt,
 
 	/* Copy the IP header */
 
-	skb->network_header = skb->tail;
+	tail_offset = skb_tail_offset(skb);
+	if (tail_offset > 0xffff) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+	skb_set_network_header(skb, tail_offset);
 	skb_put(skb, ihl);
 	skb_copy_to_linear_data(skb, pkt->data, ihl);
 	ip_hdr(skb)->protocol = 0;	/* Flag to the kernel this is a route add */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail
  2013-05-29  5:27 ` [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail Simon Horman
@ 2013-05-29  5:35   ` Eric Dumazet
  2013-05-29  5:44     ` David Miller
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Dumazet @ 2013-05-29  5:35 UTC (permalink / raw)
  To: Simon Horman; +Cc: David Miller, netdev

On Wed, 2013-05-29 at 14:27 +0900, Simon Horman wrote:
> This corrects an regression introduced by "net: Use 16bits for *_headers
> fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set. In
> that case skb->tail will be a pointer however skb->network_header is now
> an offset.
> 
> This patch corrects the problem by adding a wrapper to return skb tail as
> an offset regardless of the value of NET_SKBUFF_DATA_USES_OFFSET. It seems
> that skb->tail that this offset may be more than 64k and some care has been
> taken to treat such cases as an error.
> 
> Signed-off-by: Simon Horman <horms@verge.net.au>
> ---
>  include/linux/skbuff.h |    9 +++++++++
>  net/core/netpoll.c     |    9 ++++++++-
>  net/core/pktgen.c      |   16 ++++++++++++++--
>  net/ipv4/ipmr.c        |    8 +++++++-
>  4 files changed, 38 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 8f2b830..26ed287 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -1391,6 +1391,11 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
>  	skb_reset_tail_pointer(skb);
>  	skb->tail += offset;
>  }
> +
> +static inline __u64 skb_tail_offset(const struct sk_buff *skb)
> +{
> +	return skb->tail;
> +}
>  #else /* NET_SKBUFF_DATA_USES_OFFSET */
>  static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
>  {
> @@ -1407,6 +1412,10 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
>  	skb->tail = skb->data + offset;
>  }
>  
> +static inline __u64 skb_tail_offset(const struct sk_buff *skb)
> +{
> +	return skb->tail - skb->head;
> +}
>  #endif /* NET_SKBUFF_DATA_USES_OFFSET */
>  

Are you sure __u64 is needed on 32bit arches ?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail
  2013-05-29  5:35   ` Eric Dumazet
@ 2013-05-29  5:44     ` David Miller
  2013-05-29  6:01       ` Simon Horman
  0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2013-05-29  5:44 UTC (permalink / raw)
  To: eric.dumazet; +Cc: horms, netdev

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 28 May 2013 22:35:51 -0700

> Are you sure __u64 is needed on 32bit arches ?

It should be "unsigned long" or similar.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail
  2013-05-29  5:44     ` David Miller
@ 2013-05-29  6:01       ` Simon Horman
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-29  6:01 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev

On Tue, May 28, 2013 at 10:44:33PM -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Tue, 28 May 2013 22:35:51 -0700
> 
> > Are you sure __u64 is needed on 32bit arches ?
> 
> It should be "unsigned long" or similar.

Thanks, I will fix that and re-post.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header
  2013-05-29  5:27 ` [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header Simon Horman
@ 2013-05-29 19:31   ` Ben Hutchings
  2013-05-31  6:21     ` Simon Horman
  0 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2013-05-29 19:31 UTC (permalink / raw)
  To: Simon Horman; +Cc: David Miller, netdev

On Wed, 2013-05-29 at 14:27 +0900, Simon Horman wrote:
> This corrects an regression introduced by "net: Use 16bits for *_headers
> fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set.

So how about adding 'typedef u16 sk_buff_data_t;'?

> In
> that case sk_buff_data_t will be a pointer, however,
> skb->{network,transport}_header is now __u16.
> 
> Signed-off-by: Simon Horman <horms@verge.net.au>
> ---
>  net/sctp/input.c |    2 +-
>  net/sctp/ipv6.c  |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/sctp/input.c b/net/sctp/input.c
> index 4b2c831..e328fe8 100644
> --- a/net/sctp/input.c
> +++ b/net/sctp/input.c
> @@ -589,7 +589,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
>  	struct sctp_association *asoc = NULL;
>  	struct sctp_transport *transport;
>  	struct inet_sock *inet;
> -	sk_buff_data_t saveip, savesctp;
> +	__be16 saveip, savesctp;
[...]

__be16??

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header
  2013-05-29 19:31   ` Ben Hutchings
@ 2013-05-31  6:21     ` Simon Horman
  0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2013-05-31  6:21 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev

On Wed, May 29, 2013 at 08:31:12PM +0100, Ben Hutchings wrote:
> On Wed, 2013-05-29 at 14:27 +0900, Simon Horman wrote:
> > This corrects an regression introduced by "net: Use 16bits for *_headers
> > fields of struct skbuff" when NET_SKBUFF_DATA_USES_OFFSET is not set.
> 
> So how about adding 'typedef u16 sk_buff_data_t;'?
> 
> > In
> > that case sk_buff_data_t will be a pointer, however,
> > skb->{network,transport}_header is now __u16.
> > 
> > Signed-off-by: Simon Horman <horms@verge.net.au>
> > ---
> >  net/sctp/input.c |    2 +-
> >  net/sctp/ipv6.c  |    2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/net/sctp/input.c b/net/sctp/input.c
> > index 4b2c831..e328fe8 100644
> > --- a/net/sctp/input.c
> > +++ b/net/sctp/input.c
> > @@ -589,7 +589,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
> >  	struct sctp_association *asoc = NULL;
> >  	struct sctp_transport *transport;
> >  	struct inet_sock *inet;
> > -	sk_buff_data_t saveip, savesctp;
> > +	__be16 saveip, savesctp;
> [...]
> 
> __be16??

Ooops. I will fix that.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-05-31  6:29 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-29  5:27 [PATCH 0/7] Fix fallout from conversion of skb headers to 16bit offsets Simon Horman
2013-05-29  5:27 ` [PATCH 1/7] isdn: Correct comparison of skb->tail and skb-transport_header Simon Horman
2013-05-29  5:27 ` [PATCH 2/7] cxgb3: Correct comparisons and calculations using " Simon Horman
2013-05-29  5:27 ` [PATCH 3/7] net: " Simon Horman
2013-05-29  5:27 ` [PATCH 4/7] ipv6: " Simon Horman
2013-05-29  5:27 ` [PATCH 5/7] ipv4: " Simon Horman
2013-05-29  5:27 ` [PATCH 6/7] sctp: Correct access to skb->{network,transport}_header Simon Horman
2013-05-29 19:31   ` Ben Hutchings
2013-05-31  6:21     ` Simon Horman
2013-05-29  5:27 ` [PATCH 7/7] net,ipv4,ipv6: Correct assignment of skb->network_header to skb->tail Simon Horman
2013-05-29  5:35   ` Eric Dumazet
2013-05-29  5:44     ` David Miller
2013-05-29  6:01       ` Simon Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.