: Fix skb->cb conflicts with IP
Subsystems (2)
commit eced67957ee99f7b5fafdc73a58bcd037a1789b2
Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200
[DCCP]: Fix skb->cb conflicts with IP
dev_queue_xmit() and the other IP output functions expect to get a skb with clear or properly initialized skb->cb. Unlike TCP and UDP, the dccp_skb_cb doesn't contain a struct inet_skb_parm at the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditional POST_ROUTING hook invocation, making the packet bypass the hook.
Add a inet_skb_parm/inet6_skb_parm union to the beginning of dccp_skb_cb to avoid clashes. Also add a BUILD_BUG_ON to make sure it fits in the cb.
net/dccp/dccp.h +6 -0
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,* This is used for transmission as well as for reception. */ struct dccp_skb_cb { +union { +struct inet_skb_parm h4; +#if defined(CONFIG_IPV6 ) || defined (CONFIG_IPV6_MODULE ) +struct inet6_skb_parm h6; +#endif + } header;__u8 dccpd_type:4 ;__u8 dccpd_ccval:4 ; __u8 dccpd_reset_code,
net/dccp/proto.c +3 -0
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)int ehash_order, bhash_order, i;int rc = -ENOBUFS ; +BUILD_BUG_ON (sizeof (struct dccp_skb_cb ) > + FIELD_SIZEOF(struct sk_buff, cb)); + dccp_hashinfo.bind_bucket_cachep = kmem_cache_create("dccp_bind_bucket", sizeof(struct inet_bind_bucket), 0,
Arnaldo,
just a thought - I recall that there used to be a bug related to this, which required to insert the following before sending an skb:
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt))
This was about 1+1/2 .. 2 years ago and lead to crashes when the memset was removed. Maybe with this solution the memsets are then no longer necessary? The reference is
* output.c:dccp_transmit_skb()
* ipv4.c:dccp_v4_send_response()
Gerrit
| commit eced67957ee99f7b5fafdc73a58bcd037a1789b2 | Author: Patrick McHardy <[email protected]> | Date: Fri Apr 4 14:10:23 2008 +0200 | | [DCCP]: Fix skb->cb conflicts with IP | | dev_queue_xmit() and the other IP output functions expect to get a skb | with clear or properly initialized skb->cb. Unlike TCP and UDP, the | dccp_skb_cb doesn't contain a struct inet_skb_parm at the beginning, | so the DCCP-specific data is interpreted by the IP output functions. | This can cause false negatives for the conditional POST_ROUTING hook | invocation, making the packet bypass the hook. | | Add a inet_skb_parm/inet6_skb_parm union to the beginning of | dccp_skb_cb to avoid clashes. Also add a BUILD_BUG_ON to make | sure it fits in the cb. | | Signed-off-by: Patrick McHardy <[email protected]> | | diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h | index fe7726b..f44d492 100644 | --- a/net/dccp/dccp.h | +++ b/net/dccp/dccp.h | @@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk, | * This is used for transmission as well as for reception. | */ | struct dccp_skb_cb { | + union { | + struct inet_skb_parm h4; | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | + struct inet6_skb_parm h6; | +#endif | + } header; | __u8 dccpd_type:4; | __u8 dccpd_ccval:4; | __u8 dccpd_reset_code, | diff --git a/net/dccp/proto.c b/net/dccp/proto.c | index e3f5d37..c91d3c1 100644 | --- a/net/dccp/proto.c | +++ b/net/dccp/proto.c | @@ -1057,6 +1057,9 @@ static int __init dccp_init(void) | int ehash_order, bhash_order, i; | int rc = -ENOBUFS; | | + BUILD_BUG_ON(sizeof(struct dccp_skb_cb) > | + FIELD_SIZEOF(struct sk_buff, cb)); | + | dccp_hashinfo.bind_bucket_cachep | kmem_cache_create("dccp_bind_bucket", | sizeof(struct inet_bind_bucket), 0,
Signature · 1 line
The University of Aberdeen is a charity registered in Scotland, No SC013683.
Quoted 5 lines · Gerrit Renker
Arnaldo,
just a thought - I recall that there used to be a bug related to this, which required to insert the following before sending an skb:
Quoted 7 lines
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt))This was about 1+1/2 .. 2 years ago and lead to crashes when the memset was removed. Maybe with this solution the memsets are then no longer necessary? The reference is
* output.c:dccp_transmit_skb()
* ipv4.c:dccp_v4_send_response()
Yes, that shouldn't be needed anymore with this patch.
Em Fri, Apr 04, 2008 at 02:25:25PM +0100, Gerrit Renker escreveu:
Quoted 5 lines
Arnaldo,
just a thought - I recall that there used to be a bug related to this, which required to insert the following before sending an skb:
Quoted 7 lines
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt))This was about 1+1/2 .. 2 years ago and lead to crashes when the memset was removed. Maybe with this solution the memsets are then no longer necessary? The reference is
* output.c:dccp_transmit_skb()
* ipv4.c:dccp_v4_send_response()
Well spotted, yes, those can now be safely removed, since we don't touch the initial inet6?_skb_parm area it will remain as zeros (alloc_skb did that for us) and we don't have to zero it anymore before passing it to IP.
- Arnaldo
Quoted 58 lines
Gerrit
| commit eced67957ee99f7b5fafdc73a58bcd037a1789b2 | Author: Patrick McHardy <[email protected]> | Date: Fri Apr 4 14:10:23 2008 +0200 | | [DCCP]: Fix skb->cb conflicts with IP | | dev_queue_xmit() and the other IP output functions expect to get a skb | with clear or properly initialized skb->cb. Unlike TCP and UDP, the | dccp_skb_cb doesn't contain a struct inet_skb_parm at the beginning, | so the DCCP-specific data is interpreted by the IP output functions. | This can cause false negatives for the conditional POST_ROUTING hook | invocation, making the packet bypass the hook. | | Add a inet_skb_parm/inet6_skb_parm union to the beginning of | dccp_skb_cb to avoid clashes. Also add a BUILD_BUG_ON to make | sure it fits in the cb. | | Signed-off-by: Patrick McHardy <[email protected]> | | diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h | index fe7726b..f44d492 100644 | --- a/net/dccp/dccp.h | +++ b/net/dccp/dccp.h | @@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk, | * This is used for transmission as well as for reception. | */ | struct dccp_skb_cb { | + union { | + struct inet_skb_parm h4; | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | + struct inet6_skb_parm h6; | +#endif | + } header; | __u8 dccpd_type:4; | __u8 dccpd_ccval:4; | __u8 dccpd_reset_code, | diff --git a/net/dccp/proto.c b/net/dccp/proto.c | index e3f5d37..c91d3c1 100644 | --- a/net/dccp/proto.c | +++ b/net/dccp/proto.c | @@ -1057,6 +1057,9 @@ static int __init dccp_init(void) | int ehash_order, bhash_order, i; | int rc = -ENOBUFS; | | + BUILD_BUG_ON(sizeof(struct dccp_skb_cb) > | + FIELD_SIZEOF(struct sk_buff, cb)); | + | dccp_hashinfo.bind_bucket_cachep > | kmem_cache_create("dccp_bind_bucket", | sizeof(struct inet_bind_bucket), 0,Signature · 1 line
The University of Aberdeen is a charity registered in Scotland, No SC013683.
Arnaldo Carvalho de Melo
Acked-byEm Fri, Apr 04, 2008 at 02:13:16PM +0200, Patrick McHardy escreveu:
Quoted 13 lines
commit
eced67957ee99f7b5fafdc73a58bcd037a1789b2Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to get a skb with clear or properly initializedskb->cb. Unlike TCP and UDP, thedccp_skb_cbdoesn't contain a structinet_skb_parmat the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditionalPOST_ROUTINGhook invocation, making the packet bypass the hook.
Quoted 5 lines
Add a inet_skb_parm/inet6_skb_parm union to the beginning of
dccp_skb_cbto avoid clashes. Also add aBUILD_BUG_ONto make sure it fits in the cb.Signed-off-by Patrick McHardy <[email protected]>
Thanks Patrick,
Quoted 19 lines · Arnaldo Carvalho de Melo
Em Fri, Apr 04, 2008 at 02:13:16PM +0200, Patrick McHardy escreveu:
Quoted 17 lines
commit
eced67957ee99f7b5fafdc73a58bcd037a1789b2Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to get a skb with clear or properly initializedskb->cb. Unlike TCP and UDP, thedccp_skb_cbdoesn't contain a structinet_skb_parmat the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditionalPOST_ROUTINGhook invocation, making the packet bypass the hook.Add a inet_skb_parm/inet6_skb_parm union to the beginning of
dccp_skb_cbto avoid clashes. Also add aBUILD_BUG_ONto make sure it fits in the cb.
Quoted 5 lines
Quoted 1 line
Signed-off-by Patrick McHardy <[email protected]>Thanks Patrick,
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
commit eced67957ee99f7b5fafdc73a58bcd037a1789b2
Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200
[DCCP]: Fix skb->cb conflicts with IP
dev_queue_xmit() and the other IP output functions expect to get a skb with clear or properly initialized skb->cb. Unlike TCP and UDP, the dccp_skb_cb doesn't contain a struct inet_skb_parm at the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditional POST_ROUTING hook invocation, making the packet bypass the hook.
Add a inet_skb_parm/inet6_skb_parm union to the beginning of dccp_skb_cb to avoid clashes. Also add a BUILD_BUG_ON to make sure it fits in the cb.
net/dccp/dccp.h +6 -0
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,* This is used for transmission as well as for reception. */ struct dccp_skb_cb { +union { +struct inet_skb_parm h4; +#if defined(CONFIG_IPV6 ) || defined (CONFIG_IPV6_MODULE ) +struct inet6_skb_parm h6; +#endif + } header;__u8 dccpd_type:4 ;__u8 dccpd_ccval:4 ; __u8 dccpd_reset_code,
net/dccp/proto.c +3 -0
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)int ehash_order, bhash_order, i;int rc = -ENOBUFS ; +BUILD_BUG_ON (sizeof (struct dccp_skb_cb ) > + FIELD_SIZEOF(struct sk_buff, cb)); + dccp_hashinfo.bind_bucket_cachep = kmem_cache_create("dccp_bind_bucket", sizeof(struct inet_bind_bucket), 0,
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to
<snip>
Quoted 6 lines
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
If it is not too much work, can you please also remove the two attached hunks which are now redundant thanks to the above patch.
The University of Aberdeen is a charity registered in Scotland, No SC013683.
net/dccp/ipv4.c +0 -1
@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, dh->dccph_checksum =dccp_v4_csum_finish (skb, ireq->loc_addr, ireq->rmt_addr); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err =ip_build_and_send_pkt (skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt);
net/dccp/output.c +0 -1
@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)DCCP_INC_STATS (DCCP_MIB_OUTSEGS ); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err = icsk->icsk_af_ops->queue_xmit (skb,0 );return net_xmit_eval (err); }
Quoted 10 lines · Gerrit Renker
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to<snip>
Quoted 5 lines
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
If it is not too much work, can you please also remove the two attached hunks which are now redundant thanks to the above patch.
I've added it to the patch, thanks.
commit eced67957ee99f7b5fafdc73a58bcd037a1789b2
Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200
[DCCP]: Fix skb->cb conflicts with IP
dev_queue_xmit() and the other IP output functions expect to get a skb with clear or properly initialized skb->cb. Unlike TCP and UDP, the dccp_skb_cb doesn't contain a struct inet_skb_parm at the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditional POST_ROUTING hook invocation, making the packet bypass the hook.
Add a inet_skb_parm/inet6_skb_parm union to the beginning of dccp_skb_cb to avoid clashes. Also add a BUILD_BUG_ON to make sure it fits in the cb.
[ Combined with patch from Gerrit Renker to remove two now unnecessary
memsets of IPCB(skb)->opt ]
net/dccp/dccp.h +6 -0
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,* This is used for transmission as well as for reception. */ struct dccp_skb_cb { +union { +struct inet_skb_parm h4; +#if defined(CONFIG_IPV6 ) || defined (CONFIG_IPV6_MODULE ) +struct inet6_skb_parm h6; +#endif + } header;__u8 dccpd_type:4 ;__u8 dccpd_ccval:4 ; __u8 dccpd_reset_code,
net/dccp/proto.c +3 -0
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)int ehash_order, bhash_order, i;int rc = -ENOBUFS ; +BUILD_BUG_ON (sizeof (struct dccp_skb_cb ) > + FIELD_SIZEOF(struct sk_buff, cb)); + dccp_hashinfo.bind_bucket_cachep = kmem_cache_create("dccp_bind_bucket", sizeof(struct inet_bind_bucket), 0,
net/dccp/ipv4.c +0 -1
@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, dh->dccph_checksum =dccp_v4_csum_finish (skb, ireq->loc_addr, ireq->rmt_addr); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err =ip_build_and_send_pkt (skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt);
net/dccp/output.c +0 -1
@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)DCCP_INC_STATS (DCCP_MIB_OUTSEGS ); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err = icsk->icsk_af_ops->queue_xmit (skb,0 );return net_xmit_eval (err); }
Arnaldo Carvalho de Melo
Acked-byEm Fri, Apr 11, 2008 at 04:03:10PM +0200, Patrick McHardy escreveu:
Quoted 9 lines
Quoted 8 lines · Gerrit Renker
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to<snip>
Quoted 5 lines
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
Quoted 5 lines
Quoted 2 lines
If it is not too much work, can you please also remove the two attached hunks which are now redundant thanks to the above patch.
I've added it to the patch, thanks.
Quoted 72 lines
commit
eced67957ee99f7b5fafdc73a58bcd037a1789b2Author: Patrick McHardy <[email protected]> Date: Fri Apr 4 14:10:23 2008 +0200[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to get a skb with clear or properly initializedskb->cb. Unlike TCP and UDP, thedccp_skb_cbdoesn't contain a structinet_skb_parmat the beginning, so the DCCP-specific data is interpreted by the IP output functions. This can cause false negatives for the conditionalPOST_ROUTINGhook invocation, making the packet bypass the hook.Add a inet_skb_parm/inet6_skb_parm union to the beginning of
dccp_skb_cbto avoid clashes. Also add aBUILD_BUG_ONto make sure it fits in the cb.[ Combined with patch from Gerrit Renker to remove two now unnecessary
memsets of IPCB(skb)->opt ]Signed-off-by Patrick McHardy <[email protected]>net/dccp/dccp.h +6
-0@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,* This is used for transmission as well as for reception. */ struct dccp_skb_cb { +union { +struct inet_skb_parm h4; +#if defined(CONFIG_IPV6 ) || defined (CONFIG_IPV6_MODULE ) +struct inet6_skb_parm h6; +#endif + } header;__u8 dccpd_type:4 ;__u8 dccpd_ccval:4 ; __u8 dccpd_reset_code,net/dccp/proto.c +3
-0@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)int ehash_order, bhash_order, i;int rc = -ENOBUFS ; +BUILD_BUG_ON (sizeof (struct dccp_skb_cb ) > + FIELD_SIZEOF(struct sk_buff, cb)); + dccp_hashinfo.bind_bucket_cachep > kmem_cache_create("dccp_bind_bucket", sizeof(struct inet_bind_bucket), 0,net/dccp/ipv4.c +0
-1@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, dh->dccph_checksum =dccp_v4_csum_finish (skb, ireq->loc_addr, ireq->rmt_addr); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err =ip_build_and_send_pkt (skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt);net/dccp/output.c +0
-1@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)DCCP_INC_STATS (DCCP_MIB_OUTSEGS ); -memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt)); err = icsk->icsk_af_ops->queue_xmit (skb,0 );return net_xmit_eval (err); }
David Miller
maintainerFrom: Arnaldo Carvalho de Melo <[email protected]>
Date: Fri, 11 Apr 2008 11:05:01 -0300
Quoted 10 lines
Em Fri, Apr 11, 2008 at 04:03:10PM +0200, Patrick McHardy escreveu:
Quoted 9 lines
Quoted 8 lines · Gerrit Renker
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to<snip>
Quoted 5 lines
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
If it is not too much work, can you please also remove the two attached hunks which are now redundant thanks to the above patch.
I've added it to the patch, thanks.
And for the record, I have it and will merge :-)
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Fri, 11 Apr 2008 11:05:01 -0300
Quoted 10 lines
Em Fri, Apr 11, 2008 at 04:03:10PM +0200, Patrick McHardy escreveu:
Quoted 9 lines
Quoted 8 lines · Gerrit Renker
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
[DCCP]: Fix
skb->cbconflicts with IP
dev_queue_xmit()and the other IP output functions expect to<snip>
Quoted 5 lines
Dave, I'm not sure whether you've missed this or expect it to go through Arnaldo, just want to make sure it doesn't get missed because of a misunderstanding :)
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
If it is not too much work, can you please also remove the two attached hunks which are now redundant thanks to the above patch.
I've added it to the patch, thanks.
Applied to net-2.6, thanks everyone.