netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] net: dev_queue_xmit_nit fixes
@ 2013-01-08 18:51 Daniel Borkmann
  2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
  2013-01-08 18:51 ` [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference Daniel Borkmann
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel Borkmann @ 2013-01-08 18:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Daniel Borkmann

First patch is a fix for the netdev discussion ``PROBLEM: Software injected
vlan tagged packets are unable to be identified using recent BPF
modifications'' and the second one I spotted while doing the first fix.

Daniel Borkmann (2):
  net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  net: dev_queue_xmit_nit: fix potential NULL ptr dereference

 net/core/dev.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

-- 
1.7.11.7

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

* [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 18:51 [PATCH net 0/2] net: dev_queue_xmit_nit fixes Daniel Borkmann
@ 2013-01-08 18:51 ` Daniel Borkmann
  2013-01-08 19:54   ` Ani Sinha
                     ` (2 more replies)
  2013-01-08 18:51 ` [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference Daniel Borkmann
  1 sibling, 3 replies; 10+ messages in thread
From: Daniel Borkmann @ 2013-01-08 18:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Daniel Borkmann, Eric Dumazet, Ani Sinha, Jiri Pirko

VLAN packets that are locally injected through taps will loose their
skb->vlan_tci value when they pass dev_hard_start_xmit and get looped
back to a packet sniffer via dev_queue_xmit_nit. Besides others, this
meta data is used in Linux socket filtering for VLANs. Tested with a
VLAN ancillary ops filter.

Patch is based on a previous version by Jiri Pirko.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ani Sinha <ani@aristanetworks.com>
Cc: Jiri Pirko <jpirko@redhat.com>
Reported-by: Paul Pearce <pearce@cs.berkeley.edu>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/core/dev.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/net/core/dev.c b/net/core/dev.c
index 515473e..723dcd0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1775,6 +1775,19 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 	struct packet_type *ptype;
 	struct sk_buff *skb2 = NULL;
 	struct packet_type *pt_prev = NULL;
+	struct ethhdr *ehdr;
+
+	/* Network taps could make use of skb->vlan_tci, which got wiped
+	 * out. Hence, we need to reset it correctly.
+	 */
+	skb_reset_mac_header(skb);
+	ehdr = eth_hdr(skb);
+
+	if (ehdr->h_proto == __constant_htons(ETH_P_8021Q)) {
+		skb2 = vlan_untag(skb);
+		if (likely(skb2))
+			skb = skb2;
+	}
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
-- 
1.7.11.7

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

* [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference
  2013-01-08 18:51 [PATCH net 0/2] net: dev_queue_xmit_nit fixes Daniel Borkmann
  2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
@ 2013-01-08 18:51 ` Daniel Borkmann
  2013-01-08 19:22   ` Eric Dumazet
  1 sibling, 1 reply; 10+ messages in thread
From: Daniel Borkmann @ 2013-01-08 18:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Daniel Borkmann, Changli Gao, Eric Dumazet

Commit 71d9dec24dce548bf699815c976cf063ad9257e2 (``net: increase
skb->users instead of skb_clone()'') introduced a skb_clone in
dev_queue_xmit_nit that, when NULL, leaves the loop, but can still
be injected into pt_prev->func().

Cc: Changli Gao <xiaosuo@gmail.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/core/dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 723dcd0..6c35c33 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1827,7 +1827,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 			pt_prev = ptype;
 		}
 	}
-	if (pt_prev)
+	if (skb2 && pt_prev)
 		pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
 	rcu_read_unlock();
 }
-- 
1.7.11.7

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

* Re: [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference
  2013-01-08 18:51 ` [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference Daniel Borkmann
@ 2013-01-08 19:22   ` Eric Dumazet
  2013-01-08 19:38     ` Daniel Borkmann
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2013-01-08 19:22 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: David Miller, netdev, Changli Gao

On Tue, 2013-01-08 at 19:51 +0100, Daniel Borkmann wrote:
> Commit 71d9dec24dce548bf699815c976cf063ad9257e2 (``net: increase
> skb->users instead of skb_clone()'') introduced a skb_clone in
> dev_queue_xmit_nit that, when NULL, leaves the loop, but can still
> be injected into pt_prev->func().
> 
> Cc: Changli Gao <xiaosuo@gmail.com>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
>  net/core/dev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 723dcd0..6c35c33 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1827,7 +1827,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
>  			pt_prev = ptype;
>  		}
>  	}
> -	if (pt_prev)
> +	if (skb2 && pt_prev)
>  		pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
>  	rcu_read_unlock();
>  }

My opinion is this patch is not needed.

pt_prev can be set only if skb2 is not NULL

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

* Re: [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference
  2013-01-08 19:22   ` Eric Dumazet
@ 2013-01-08 19:38     ` Daniel Borkmann
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Borkmann @ 2013-01-08 19:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Changli Gao

On 01/08/2013 08:22 PM, Eric Dumazet wrote:
> On Tue, 2013-01-08 at 19:51 +0100, Daniel Borkmann wrote:
>> Commit 71d9dec24dce548bf699815c976cf063ad9257e2 (``net: increase
>> skb->users instead of skb_clone()'') introduced a skb_clone in
>> dev_queue_xmit_nit that, when NULL, leaves the loop, but can still
>> be injected into pt_prev->func().
>>
>> Cc: Changli Gao <xiaosuo@gmail.com>
>> Cc: Eric Dumazet <eric.dumazet@gmail.com>
>> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
>> ---
>>   net/core/dev.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 723dcd0..6c35c33 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -1827,7 +1827,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
>>   			pt_prev = ptype;
>>   		}
>>   	}
>> -	if (pt_prev)
>> +	if (skb2 && pt_prev)
>>   		pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
>>   	rcu_read_unlock();
>>   }
>
> My opinion is this patch is not needed.
>
> pt_prev can be set only if skb2 is not NULL

Agreed, I missed that, thanks.

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

* Re: [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
@ 2013-01-08 19:54   ` Ani Sinha
  2013-01-08 20:04   ` Eric Dumazet
  2013-01-08 20:14   ` Jiri Pirko
  2 siblings, 0 replies; 10+ messages in thread
From: Ani Sinha @ 2013-01-08 19:54 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: David Miller, netdev, Eric Dumazet, Jiri Pirko

Agreed with the fix. This fixes the issue introduced by this change :l


On Tue, Jan 8, 2013 at 10:51 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
> VLAN packets that are locally injected through taps will loose their
> skb->vlan_tci value when they pass dev_hard_start_xmit and get looped
> back to a packet sniffer via dev_queue_xmit_nit. Besides others, this
> meta data is used in Linux socket filtering for VLANs. Tested with a
> VLAN ancillary ops filter.
>
> Patch is based on a previous version by Jiri Pirko.
>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Ani Sinha <ani@aristanetworks.com>
> Cc: Jiri Pirko <jpirko@redhat.com>
> Reported-by: Paul Pearce <pearce@cs.berkeley.edu>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>

Acked-by: Ani Sinha <ani@aristanetworks.com>

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

* Re: [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
  2013-01-08 19:54   ` Ani Sinha
@ 2013-01-08 20:04   ` Eric Dumazet
  2013-01-08 20:22     ` Jiri Pirko
  2013-01-08 20:14   ` Jiri Pirko
  2 siblings, 1 reply; 10+ messages in thread
From: Eric Dumazet @ 2013-01-08 20:04 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: David Miller, netdev, Ani Sinha, Jiri Pirko

On Tue, 2013-01-08 at 19:51 +0100, Daniel Borkmann wrote:
> VLAN packets that are locally injected through taps will loose their
> skb->vlan_tci value when they pass dev_hard_start_xmit and get looped
> back to a packet sniffer via dev_queue_xmit_nit. Besides others, this
> meta data is used in Linux socket filtering for VLANs. Tested with a
> VLAN ancillary ops filter.
> 
> Patch is based on a previous version by Jiri Pirko.
> 
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Ani Sinha <ani@aristanetworks.com>
> Cc: Jiri Pirko <jpirko@redhat.com>
> Reported-by: Paul Pearce <pearce@cs.berkeley.edu>
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
>  net/core/dev.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 515473e..723dcd0 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1775,6 +1775,19 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
>  	struct packet_type *ptype;
>  	struct sk_buff *skb2 = NULL;
>  	struct packet_type *pt_prev = NULL;
> +	struct ethhdr *ehdr;
> +
> +	/* Network taps could make use of skb->vlan_tci, which got wiped
> +	 * out. Hence, we need to reset it correctly.
> +	 */
> +	skb_reset_mac_header(skb);
> +	ehdr = eth_hdr(skb);
> +
> +	if (ehdr->h_proto == __constant_htons(ETH_P_8021Q)) {
> +		skb2 = vlan_untag(skb);
> +		if (likely(skb2))
> +			skb = skb2;
> +	}
>  
>  	rcu_read_lock();
>  	list_for_each_entry_rcu(ptype, &ptype_all, list) {

This patch is wrong (it adds a leak), and not needed.

If a packet has no vlan_tci, its for a good reason.

We want sniffer see the packet content as is.

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

* Re: [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
  2013-01-08 19:54   ` Ani Sinha
  2013-01-08 20:04   ` Eric Dumazet
@ 2013-01-08 20:14   ` Jiri Pirko
  2 siblings, 0 replies; 10+ messages in thread
From: Jiri Pirko @ 2013-01-08 20:14 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: David Miller, netdev, Eric Dumazet, Ani Sinha, Jiri Pirko

Tue, Jan 08, 2013 at 07:51:32PM CET, dborkman@redhat.com wrote:
>VLAN packets that are locally injected through taps will loose their
>skb->vlan_tci value when they pass dev_hard_start_xmit and get looped
>back to a packet sniffer via dev_queue_xmit_nit. Besides others, this
>meta data is used in Linux socket filtering for VLANs. Tested with a
>VLAN ancillary ops filter.
>
>Patch is based on a previous version by Jiri Pirko.
>
>Cc: Eric Dumazet <eric.dumazet@gmail.com>
>Cc: Ani Sinha <ani@aristanetworks.com>
>Cc: Jiri Pirko <jpirko@redhat.com>
>Reported-by: Paul Pearce <pearce@cs.berkeley.edu>
>Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
>---
> net/core/dev.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index 515473e..723dcd0 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -1775,6 +1775,19 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
> 	struct packet_type *ptype;
> 	struct sk_buff *skb2 = NULL;
> 	struct packet_type *pt_prev = NULL;
>+	struct ethhdr *ehdr;
>+
>+	/* Network taps could make use of skb->vlan_tci, which got wiped
>+	 * out. Hence, we need to reset it correctly.
>+	 */
>+	skb_reset_mac_header(skb);
>+	ehdr = eth_hdr(skb);
>+
>+	if (ehdr->h_proto == __constant_htons(ETH_P_8021Q)) {
>+		skb2 = vlan_untag(skb);
>+		if (likely(skb2))
>+			skb = skb2;
>+	}

	Hmm, nitpick, I think that better would be to do:
		skb = vlan_untag(skb);
		if (unlikely(!skb))
			return;
	
	I believe that better is to deliver skbs in consistent way and
	to do not deliver at all in case of -ENOMEM

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

* Re: [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 20:04   ` Eric Dumazet
@ 2013-01-08 20:22     ` Jiri Pirko
  2013-01-08 20:42       ` Eric Dumazet
  0 siblings, 1 reply; 10+ messages in thread
From: Jiri Pirko @ 2013-01-08 20:22 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Daniel Borkmann, David Miller, netdev, Ani Sinha, Jiri Pirko

Tue, Jan 08, 2013 at 09:04:52PM CET, eric.dumazet@gmail.com wrote:
>On Tue, 2013-01-08 at 19:51 +0100, Daniel Borkmann wrote:
>> VLAN packets that are locally injected through taps will loose their
>> skb->vlan_tci value when they pass dev_hard_start_xmit and get looped
>> back to a packet sniffer via dev_queue_xmit_nit. Besides others, this
>> meta data is used in Linux socket filtering for VLANs. Tested with a
>> VLAN ancillary ops filter.
>> 
>> Patch is based on a previous version by Jiri Pirko.
>> 
>> Cc: Eric Dumazet <eric.dumazet@gmail.com>
>> Cc: Ani Sinha <ani@aristanetworks.com>
>> Cc: Jiri Pirko <jpirko@redhat.com>
>> Reported-by: Paul Pearce <pearce@cs.berkeley.edu>
>> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
>> ---
>>  net/core/dev.c | 13 +++++++++++++
>>  1 file changed, 13 insertions(+)
>> 
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 515473e..723dcd0 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -1775,6 +1775,19 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
>>  	struct packet_type *ptype;
>>  	struct sk_buff *skb2 = NULL;
>>  	struct packet_type *pt_prev = NULL;
>> +	struct ethhdr *ehdr;
>> +
>> +	/* Network taps could make use of skb->vlan_tci, which got wiped
>> +	 * out. Hence, we need to reset it correctly.
>> +	 */
>> +	skb_reset_mac_header(skb);
>> +	ehdr = eth_hdr(skb);
>> +
>> +	if (ehdr->h_proto == __constant_htons(ETH_P_8021Q)) {
>> +		skb2 = vlan_untag(skb);
>> +		if (likely(skb2))
>> +			skb = skb2;
>> +	}
>>  
>>  	rcu_read_lock();
>>  	list_for_each_entry_rcu(ptype, &ptype_all, list) {
>
>This patch is wrong (it adds a leak), and not needed.
>
>If a packet has no vlan_tci, its for a good reason.
>
>We want sniffer see the packet content as is.


The issue is that for exmaple in af_packet the function packet_rcv()
expects vlan_tci to be filled out as that is on RX path ensured by
__netif_receive_skb(). However on TX path, dev_queue_xmit_nit() is
called with vlan_tci cleaned in case the device does not have TX vlan
accel enabled. This patch is trying to fix this difference.

>
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value
  2013-01-08 20:22     ` Jiri Pirko
@ 2013-01-08 20:42       ` Eric Dumazet
  0 siblings, 0 replies; 10+ messages in thread
From: Eric Dumazet @ 2013-01-08 20:42 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Daniel Borkmann, David Miller, netdev, Ani Sinha, Jiri Pirko

On Tue, 2013-01-08 at 21:22 +0100, Jiri Pirko wrote:

> 
> The issue is that for exmaple in af_packet the function packet_rcv()
> expects vlan_tci to be filled out as that is on RX path ensured by
> __netif_receive_skb(). However on TX path, dev_queue_xmit_nit() is
> called with vlan_tci cleaned in case the device does not have TX vlan
> accel enabled. This patch is trying to fix this difference.

I perfectly understood that, and I repeat :

I want to see the difference.

A filter cannot expect skb->vlan_tci is set for all packets.

If a device doesn't have TX vlan accel, vlan_tci is 0.

packet sniffing is already slow, we don't want to force an extra copy
with vlan_untag() killer.

If you want to fix/extend af_packet, do this in af_packet.

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

end of thread, other threads:[~2013-01-08 20:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-08 18:51 [PATCH net 0/2] net: dev_queue_xmit_nit fixes Daniel Borkmann
2013-01-08 18:51 ` [PATCH net 1/2] net: dev_queue_xmit_nit: fix skb->vlan_tci field value Daniel Borkmann
2013-01-08 19:54   ` Ani Sinha
2013-01-08 20:04   ` Eric Dumazet
2013-01-08 20:22     ` Jiri Pirko
2013-01-08 20:42       ` Eric Dumazet
2013-01-08 20:14   ` Jiri Pirko
2013-01-08 18:51 ` [PATCH net 2/2] net: dev_queue_xmit_nit: fix potential NULL ptr dereference Daniel Borkmann
2013-01-08 19:22   ` Eric Dumazet
2013-01-08 19:38     ` Daniel Borkmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).