All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] netfilter: fix looped (broad|multi)cast's bogus MACs in NFQUEUE
@ 2011-06-08 15:18 Nicolas Cavallari
  2011-06-08 15:30 ` Florian Westphal
  0 siblings, 1 reply; 7+ messages in thread
From: Nicolas Cavallari @ 2011-06-08 15:18 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, netdev

By default, when broadcast or multicast packet are sent from a local
application, they are sent to the interface then looped by the kernel
to other local applications, going throught netfilter hooks in the process.

These looped packet have their MAC header removed from the skb by the kernel
looping code.
This confuse netfilter's netlink queue because it tries to extract a hardware
address from these packets, but extracts a part of the IP header instead.

This patch prevent NFQUEUE to include a MAC header in the netlink message
if there is none.

Signed-off-by: Nicolas Cavallari <cavallar@lri.fr>
---
To reproduce the bug, run libnetfilter_queue's nfqnl_test.c and add
some iptables -j NFQUEUE rule in PREROUTING.
Then, either ping -b 255.255.255.255 or ping nonexistenthost.local (if
avahi or another multicast dns client is configured)

If you see MAC addresses like 40:00:ff:11:0d::70 (for mdns) or
 00:00:80:11:70:62 then you can see that they match this part of the packet's
ip header :

               |flags| fragment offset|
 |ttl| protocol|       checksum       |

patch done against 2.6.39.1 but should also apply to nf-next
---
--- linux-2.6.39.1/net/netfilter/nfnetlink_queue.c	2011-06-08 14:43:41.188003302 +0200
+++ linux-2.6.39.1/net/netfilter/nfnetlink_queue.c	2011-06-08 14:46:10.892003541 +0200
@@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_
 	if (entskb->mark)
 		NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
 
-	if (indev && entskb->dev) {
+	if (indev && entskb->dev &&
+	    entskb->network_header != entskb->mac_header) {
 		struct nfqnl_msg_packet_hw phw;
 		int len = dev_parse_header(entskb, phw.hw_addr);
 		if (len) {

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

* Re: [PATCH] netfilter: fix looped (broad|multi)cast's bogus MACs in NFQUEUE
  2011-06-08 15:18 [PATCH] netfilter: fix looped (broad|multi)cast's bogus MACs in NFQUEUE Nicolas Cavallari
@ 2011-06-08 15:30 ` Florian Westphal
  2011-06-09 13:39   ` Nicolas Cavallari
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Westphal @ 2011-06-08 15:30 UTC (permalink / raw)
  To: Nicolas Cavallari; +Cc: Patrick McHardy, netfilter-devel, netdev

Nicolas Cavallari <Nicolas.Cavallari@lri.fr> wrote:
> By default, when broadcast or multicast packet are sent from a local
> application, they are sent to the interface then looped by the kernel
> to other local applications, going throught netfilter hooks in the process.
> 
> These looped packet have their MAC header removed from the skb by the kernel
> looping code.
> This confuse netfilter's netlink queue because it tries to extract a hardware
> address from these packets, but extracts a part of the IP header instead.

[..]

> patch done against 2.6.39.1 but should also apply to nf-next
> ---
> --- linux-2.6.39.1/net/netfilter/nfnetlink_queue.c	2011-06-08 14:43:41.188003302 +0200
> +++ linux-2.6.39.1/net/netfilter/nfnetlink_queue.c	2011-06-08 14:46:10.892003541 +0200
> @@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_
>  	if (entskb->mark)
>  		NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
>  
> -	if (indev && entskb->dev) {
> +	if (indev && entskb->dev &&
> +	    entskb->network_header != entskb->mac_header) {

nfnetlink_log has the same problem.

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

* Re: [PATCH] netfilter: fix looped (broad|multi)cast's bogus MACs in NFQUEUE
  2011-06-08 15:30 ` Florian Westphal
@ 2011-06-09 13:39   ` Nicolas Cavallari
  2011-06-09 13:39     ` [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling Nicolas Cavallari
  0 siblings, 1 reply; 7+ messages in thread
From: Nicolas Cavallari @ 2011-06-09 13:39 UTC (permalink / raw)
  To: fw, kaber, netfilter-devel, netdev

> nfnetlink_log has the same problem.

I also figured from source that ip_queue has the same problem too, so
the next patch fixes that too.


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

* [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling.
  2011-06-09 13:39   ` Nicolas Cavallari
@ 2011-06-09 13:39     ` Nicolas Cavallari
  2011-06-09 16:08       ` Patrick McHardy
  0 siblings, 1 reply; 7+ messages in thread
From: Nicolas Cavallari @ 2011-06-09 13:39 UTC (permalink / raw)
  To: fw, kaber, netfilter-devel, netdev; +Cc: Nicolas Cavallari

By default, when broadcast or multicast packet are sent from a local
application, they are sent to the interface then looped by the kernel
to other local applications, going throught netfilter hooks in the process.

These looped packet have their MAC header removed from the skb by the kernel
looping code.
This confuse various netfilter's netlink queue, netlink log and the
legacy ip_queue, because they try to extract a hardware
address from these packets, but extracts a part of the IP header instead.

This patch prevent NFQUEUE, NFLOG and ip_QUEUE to include a MAC header
if there is none in the packet.
---
 net/ipv4/netfilter/ip_queue.c   |    3 ++-
 net/ipv6/netfilter/ip6_queue.c  |    3 ++-
 net/netfilter/nfnetlink_log.c   |    3 ++-
 net/netfilter/nfnetlink_queue.c |    3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index f7f9bd7..5c9b9d9 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 	else
 		pmsg->outdev_name[0] = '\0';
 
-	if (entry->indev && entry->skb->dev) {
+	if (entry->indev && entry->skb->dev &&
+	    entry->skb->mac_header != entry->skb->network_header) {
 		pmsg->hw_type = entry->skb->dev->type;
 		pmsg->hw_addrlen = dev_parse_header(entry->skb,
 						    pmsg->hw_addr);
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 065fe40..2493948 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 	else
 		pmsg->outdev_name[0] = '\0';
 
-	if (entry->indev && entry->skb->dev) {
+	if (entry->indev && entry->skb->dev &&
+	    entry->skb->mac_header != entry->skb->network_header) {
 		pmsg->hw_type = entry->skb->dev->type;
 		pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr);
 	}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e0ee010..2e7ccbb 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst,
 	if (skb->mark)
 		NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
 
-	if (indev && skb->dev) {
+	if (indev && skb->dev &&
+	    skb->mac_header != skb->network_header) {
 		struct nfulnl_msg_packet_hw phw;
 		int len = dev_parse_header(skb, phw.hw_addr);
 		if (len > 0) {
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b83123f..fdd2faf 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 	if (entskb->mark)
 		NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
 
-	if (indev && entskb->dev) {
+	if (indev && entskb->dev &&
+	    entskb->mac_header != entskb->network_header) {
 		struct nfqnl_msg_packet_hw phw;
 		int len = dev_parse_header(entskb, phw.hw_addr);
 		if (len) {
-- 
1.7.5.3


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

* Re: [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling.
  2011-06-09 13:39     ` [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling Nicolas Cavallari
@ 2011-06-09 16:08       ` Patrick McHardy
  2011-06-10  7:20         ` Nicolas Cavallari
  0 siblings, 1 reply; 7+ messages in thread
From: Patrick McHardy @ 2011-06-09 16:08 UTC (permalink / raw)
  To: Nicolas Cavallari; +Cc: fw, netfilter-devel, netdev, Nicolas Cavallari

On 09.06.2011 15:39, Nicolas Cavallari wrote:
> By default, when broadcast or multicast packet are sent from a local
> application, they are sent to the interface then looped by the kernel
> to other local applications, going throught netfilter hooks in the process.
> 
> These looped packet have their MAC header removed from the skb by the kernel
> looping code.
> This confuse various netfilter's netlink queue, netlink log and the
> legacy ip_queue, because they try to extract a hardware
> address from these packets, but extracts a part of the IP header instead.
> 
> This patch prevent NFQUEUE, NFLOG and ip_QUEUE to include a MAC header
> if there is none in the packet.

Please add a Signed-off-by: line to your patch so I can apply it.
Thanks!

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

* [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling.
  2011-06-09 16:08       ` Patrick McHardy
@ 2011-06-10  7:20         ` Nicolas Cavallari
  2011-06-16 15:27           ` Patrick McHardy
  0 siblings, 1 reply; 7+ messages in thread
From: Nicolas Cavallari @ 2011-06-10  7:20 UTC (permalink / raw)
  To: kaber, fw, netfilter-devel, netdev; +Cc: Nicolas Cavallari

By default, when broadcast or multicast packet are sent from a local
application, they are sent to the interface then looped by the kernel
to other local applications, going throught netfilter hooks in the process.

These looped packet have their MAC header removed from the skb by the kernel
looping code.
This confuse various netfilter's netlink queue, netlink log and the
legacy ip_queue, because they try to extract a hardware
address from these packets, but extracts a part of the IP header instead.

This patch prevent NFQUEUE, NFLOG and ip_QUEUE to include a MAC header
if there is none in the packet.

Signed-off-by: Nicolas Cavallari <cavallar@lri.fr>
---
 net/ipv4/netfilter/ip_queue.c   |    3 ++-
 net/ipv6/netfilter/ip6_queue.c  |    3 ++-
 net/netfilter/nfnetlink_log.c   |    3 ++-
 net/netfilter/nfnetlink_queue.c |    3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index f7f9bd7..5c9b9d9 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 	else
 		pmsg->outdev_name[0] = '\0';
 
-	if (entry->indev && entry->skb->dev) {
+	if (entry->indev && entry->skb->dev &&
+	    entry->skb->mac_header != entry->skb->network_header) {
 		pmsg->hw_type = entry->skb->dev->type;
 		pmsg->hw_addrlen = dev_parse_header(entry->skb,
 						    pmsg->hw_addr);
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 065fe40..2493948 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 	else
 		pmsg->outdev_name[0] = '\0';
 
-	if (entry->indev && entry->skb->dev) {
+	if (entry->indev && entry->skb->dev &&
+	    entry->skb->mac_header != entry->skb->network_header) {
 		pmsg->hw_type = entry->skb->dev->type;
 		pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr);
 	}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e0ee010..2e7ccbb 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst,
 	if (skb->mark)
 		NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
 
-	if (indev && skb->dev) {
+	if (indev && skb->dev &&
+	    skb->mac_header != skb->network_header) {
 		struct nfulnl_msg_packet_hw phw;
 		int len = dev_parse_header(skb, phw.hw_addr);
 		if (len > 0) {
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b83123f..fdd2faf 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 	if (entskb->mark)
 		NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
 
-	if (indev && entskb->dev) {
+	if (indev && entskb->dev &&
+	    entskb->mac_header != entskb->network_header) {
 		struct nfqnl_msg_packet_hw phw;
 		int len = dev_parse_header(entskb, phw.hw_addr);
 		if (len) {
-- 
1.7.5.3


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

* Re: [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling.
  2011-06-10  7:20         ` Nicolas Cavallari
@ 2011-06-16 15:27           ` Patrick McHardy
  0 siblings, 0 replies; 7+ messages in thread
From: Patrick McHardy @ 2011-06-16 15:27 UTC (permalink / raw)
  To: Nicolas Cavallari; +Cc: fw, netfilter-devel, netdev, Nicolas Cavallari

On 10.06.2011 09:20, Nicolas Cavallari wrote:
> By default, when broadcast or multicast packet are sent from a local
> application, they are sent to the interface then looped by the kernel
> to other local applications, going throught netfilter hooks in the process.
> 
> These looped packet have their MAC header removed from the skb by the kernel
> looping code.
> This confuse various netfilter's netlink queue, netlink log and the
> legacy ip_queue, because they try to extract a hardware
> address from these packets, but extracts a part of the IP header instead.
> 
> This patch prevent NFQUEUE, NFLOG and ip_QUEUE to include a MAC header
> if there is none in the packet.

Applied, thanks Nicolas.

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

end of thread, other threads:[~2011-06-16 15:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-08 15:18 [PATCH] netfilter: fix looped (broad|multi)cast's bogus MACs in NFQUEUE Nicolas Cavallari
2011-06-08 15:30 ` Florian Westphal
2011-06-09 13:39   ` Nicolas Cavallari
2011-06-09 13:39     ` [PATCH] netfilter: fix looped (broad|multi)cast's MAC handling Nicolas Cavallari
2011-06-09 16:08       ` Patrick McHardy
2011-06-10  7:20         ` Nicolas Cavallari
2011-06-16 15:27           ` Patrick McHardy

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.