* sending VLAN packets via packet_mmap
@ 2010-09-30 19:24 Phil Sutter
2010-10-07 6:53 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2010-09-30 19:24 UTC (permalink / raw)
To: netdev; +Cc: Johann Baudy, Eric Dumazet
Hi,
support for VLAN tags in af_packet.c seems to be incomplete. While it's
possible to receive a full packet using SOCK_RAW, sending one will fail
due to size constraints. tpacket_snd() does not account for the
additional four bytes.
There are a few possible solutions to this problem. When searching for
the most appropriate one, I've been looking at tpacket_rcv() which
simply writes the whole frame out, setting tpacket2_hdr.tp_vlan_tci on
the go. So from a user's point of view, information is redundantly
available.
The actual problem in tpacket_snd() is this:
| reserve = dev->hard_header_len;
| [...]
| if (size_max > dev->mtu + reserve)
| size_max = dev->mtu + reserve;
I guess the check is there to avoid skb overflows on malicious data
input. Is this correct? Are there other reasons for it's existence?
As af_packet.c has no knowledge about VLANs (other than a call to
vlan_tx_tag_get()), I guess avoiding expensive parsing of the inserted
data for the VLAN tag should be appropriate. Nevertheless the check from
above needs to account for the additional VLAN_HLEN when the tag exists.
So a rather trivial solution would be to drop the check completely
(given no other constraints, of course), thereby giving the user a
little more ability to break things. Alternatively, one could require
that tpacket2_hdr.tp_vlan_tci be set (at least non-zero) to identify
packets containing a VLAN tag and allow the additional size (probably
mostly consistent to the logic inside tpacket_rcv()).
A third solution could be like the second one, but not accepting
prebuilt packets including VLAN header at all and using
tpacket2_hdr.tp_vlan_tci together with vlan_put_tag() to instead insert
it from inside the kernel.
Hopefully I didn't overlook something crucial. Feel free to flame me if
that's the case! :)
Greetings, Phil
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sending VLAN packets via packet_mmap
2010-09-30 19:24 sending VLAN packets via packet_mmap Phil Sutter
@ 2010-10-07 6:53 ` David Miller
2010-10-11 13:15 ` Phil Sutter
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2010-10-07 6:53 UTC (permalink / raw)
To: phil; +Cc: netdev, johann.baudy, eric.dumazet
From: Phil Sutter <phil@nwl.cc>
Date: Thu, 30 Sep 2010 21:24:14 +0200
> The actual problem in tpacket_snd() is this:
>
> | reserve = dev->hard_header_len;
> | [...]
> | if (size_max > dev->mtu + reserve)
> | size_max = dev->mtu + reserve;
>
> I guess the check is there to avoid skb overflows on malicious data
> input. Is this correct? Are there other reasons for it's existence?
We can add a special allowance of 4 extra bytes in this size check
_iff_ the device is ethernet and the NETIF_F_VLAN_CHALLENGED netdev
feature bit is not set.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: sending VLAN packets via packet_mmap
2010-10-07 6:53 ` David Miller
@ 2010-10-11 13:15 ` Phil Sutter
2010-10-11 13:25 ` [PATCH] af_packet: account for VLAN when checking packet size Phil Sutter
0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2010-10-11 13:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, johann.baudy, eric.dumazet
David,
On Wed, Oct 06, 2010 at 11:53:43PM -0700, David Miller wrote:
> From: Phil Sutter <phil@nwl.cc>
> Date: Thu, 30 Sep 2010 21:24:14 +0200
>
> > The actual problem in tpacket_snd() is this:
> >
> > | reserve = dev->hard_header_len;
> > | [...]
> > | if (size_max > dev->mtu + reserve)
> > | size_max = dev->mtu + reserve;
> >
> > I guess the check is there to avoid skb overflows on malicious data
> > input. Is this correct? Are there other reasons for it's existence?
>
> We can add a special allowance of 4 extra bytes in this size check
> _iff_ the device is ethernet and the NETIF_F_VLAN_CHALLENGED netdev
> feature bit is not set.
Making sure the device can actually handle the additional data, good
point!
Perhaps a bit philosophical, but what about NETIF_F_HW_VLAN_TX? AFAICT,
NICs providing that feature insert the VLAN header themselfs, correct?
Therefore __vlan_hwaccel_put_tag() just sets skb->vlan_tci. In order to
make use of that feature, one could always insert the VLAN header in the
kernel using vlan_put_tag(), depending on tpacket2_hdr.tp_vlan_tci
(probably in combination with VLAN_TAG_PRESENT to allow for VLAN ID 0).
Resumptively speaking, I'm probably talking about another feature
instead of solution for the bug in first place so I'll reply to this
mail with a patch implementing the suggested solution.
Greetings, Phil
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] af_packet: account for VLAN when checking packet size
2010-10-11 13:15 ` Phil Sutter
@ 2010-10-11 13:25 ` Phil Sutter
2010-10-11 14:03 ` Eric Dumazet
0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2010-10-11 13:25 UTC (permalink / raw)
To: davem; +Cc: netdev, johann.baudy, eric.dumazet
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
net/packet/af_packet.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9a17f28..ad37754 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -56,6 +56,7 @@
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <linux/if_arp.h>
#include <linux/if_packet.h>
#include <linux/wireless.h>
#include <linux/kernel.h>
@@ -983,6 +984,11 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
reserve = dev->hard_header_len;
+ /* allow VLAN packets when device supports them */
+ if (likely(dev->type == ARPHRD_ETHER) &&
+ likely(!(dev->features & NETIF_F_VLAN_CHALLENGED)))
+ reserve += VLAN_HLEN;
+
err = -ENETDOWN;
if (unlikely(!(dev->flags & IFF_UP)))
goto out_put;
--
1.7.2.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-11 13:25 ` [PATCH] af_packet: account for VLAN when checking packet size Phil Sutter
@ 2010-10-11 14:03 ` Eric Dumazet
2010-10-11 16:01 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Eric Dumazet @ 2010-10-11 14:03 UTC (permalink / raw)
To: Phil Sutter; +Cc: davem, netdev, johann.baudy
Le lundi 11 octobre 2010 à 15:25 +0200, Phil Sutter a écrit :
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
> net/packet/af_packet.c | 6 ++++++
> 1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> index 9a17f28..ad37754 100644
> --- a/net/packet/af_packet.c
> +++ b/net/packet/af_packet.c
> @@ -56,6 +56,7 @@
> #include <linux/in.h>
> #include <linux/inet.h>
> #include <linux/netdevice.h>
> +#include <linux/if_arp.h>
> #include <linux/if_packet.h>
> #include <linux/wireless.h>
> #include <linux/kernel.h>
> @@ -983,6 +984,11 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
>
> reserve = dev->hard_header_len;
>
> + /* allow VLAN packets when device supports them */
> + if (likely(dev->type == ARPHRD_ETHER) &&
> + likely(!(dev->features & NETIF_F_VLAN_CHALLENGED)))
> + reserve += VLAN_HLEN;
> +
> err = -ENETDOWN;
> if (unlikely(!(dev->flags & IFF_UP)))
> goto out_put;
If we dont test ETH_P_8021Q protocol here, we allow sending 1504 bytes
frames for MTU=1500
Should we really care ?
If not, just do
reserve = dev->hard_header_len + VLAN_HLEN;
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-11 14:03 ` Eric Dumazet
@ 2010-10-11 16:01 ` David Miller
2010-10-11 17:29 ` Phil Sutter
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2010-10-11 16:01 UTC (permalink / raw)
To: eric.dumazet; +Cc: phil, netdev, johann.baudy
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 11 Oct 2010 16:03:02 +0200
> If we dont test ETH_P_8021Q protocol here, we allow sending 1504 bytes
> frames for MTU=1500
>
> Should we really care ?
>
> If not, just do
>
> reserve = dev->hard_header_len + VLAN_HLEN;
Thats a good point, I think we need to validate the SKB protocol
field.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-11 16:01 ` David Miller
@ 2010-10-11 17:29 ` Phil Sutter
2010-10-12 17:19 ` Michael S. Tsirkin
0 siblings, 1 reply; 11+ messages in thread
From: Phil Sutter @ 2010-10-11 17:29 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev, johann.baudy
On Mon, Oct 11, 2010 at 09:01:53AM -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Mon, 11 Oct 2010 16:03:02 +0200
>
> > If we dont test ETH_P_8021Q protocol here, we allow sending 1504 bytes
> > frames for MTU=1500
> >
> > Should we really care ?
> >
> > If not, just do
> >
> > reserve = dev->hard_header_len + VLAN_HLEN;
>
> Thats a good point, I think we need to validate the SKB protocol
> field.
Which is set to the value of the passed struct sockaddr_ll field
sll_protocol. At least in the two userspace code samples I have here,
the later field is set to htons(ETH_P_ALL). So unless one changes the
API, the only way to find out the packet type is to actually parse the
given ethernet header.
Since tpacket_rcv() just interprets the vlan_tci skb field, such
detailed packet inspection is otherwise not done in af_packet.c.
Greetings, Phil
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-11 17:29 ` Phil Sutter
@ 2010-10-12 17:19 ` Michael S. Tsirkin
2010-10-12 17:40 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Michael S. Tsirkin @ 2010-10-12 17:19 UTC (permalink / raw)
To: David Miller, eric.dumazet, netdev, johann.baudy
On Mon, Oct 11, 2010 at 07:29:32PM +0200, Phil Sutter wrote:
> On Mon, Oct 11, 2010 at 09:01:53AM -0700, David Miller wrote:
> > From: Eric Dumazet <eric.dumazet@gmail.com>
> > Date: Mon, 11 Oct 2010 16:03:02 +0200
> >
> > > If we dont test ETH_P_8021Q protocol here, we allow sending 1504 bytes
> > > frames for MTU=1500
> > >
> > > Should we really care ?
> > >
> > > If not, just do
> > >
> > > reserve = dev->hard_header_len + VLAN_HLEN;
> >
> > Thats a good point, I think we need to validate the SKB protocol
> > field.
>
> Which is set to the value of the passed struct sockaddr_ll field
> sll_protocol. At least in the two userspace code samples I have here,
> the later field is set to htons(ETH_P_ALL). So unless one changes the
> API, the only way to find out the packet type is to actually parse the
> given ethernet header.
Yes, like eth_type_trans does I guess. I think we had a similar
discussion already:
http://lists.openwall.net/netdev/2010/01/06/38
Summary: if we want to make the protocol field have the correct
value for this case we need to make it work for other
transports not just for ethernet.
> Since tpacket_rcv() just interprets the vlan_tci skb field, such
> detailed packet inspection is otherwise not done in af_packet.c.
>
> Greetings, Phil
> --
> 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] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-12 17:19 ` Michael S. Tsirkin
@ 2010-10-12 17:40 ` David Miller
2010-10-22 8:41 ` Simon Horman
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2010-10-12 17:40 UTC (permalink / raw)
To: mst; +Cc: eric.dumazet, netdev, johann.baudy
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Tue, 12 Oct 2010 19:19:41 +0200
> Yes, like eth_type_trans does I guess. I think we had a similar
> discussion already:
>
> http://lists.openwall.net/netdev/2010/01/06/38
>
> Summary: if we want to make the protocol field have the correct
> value for this case we need to make it work for other
> transports not just for ethernet.
Right, so for now we should just allow 4-byte larger
than MTU TX packets, as long as the device is ethernet
and can handle VLANs properly.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-12 17:40 ` David Miller
@ 2010-10-22 8:41 ` Simon Horman
2010-10-27 15:48 ` David Miller
0 siblings, 1 reply; 11+ messages in thread
From: Simon Horman @ 2010-10-22 8:41 UTC (permalink / raw)
To: David Miller; +Cc: mst, eric.dumazet, netdev, johann.baudy
On Tue, Oct 12, 2010 at 10:40:32AM -0700, David Miller wrote:
> From: "Michael S. Tsirkin" <mst@redhat.com>
> Date: Tue, 12 Oct 2010 19:19:41 +0200
>
> > Yes, like eth_type_trans does I guess. I think we had a similar
> > discussion already:
> >
> > http://lists.openwall.net/netdev/2010/01/06/38
> >
> > Summary: if we want to make the protocol field have the correct
> > value for this case we need to make it work for other
> > transports not just for ethernet.
>
> Right, so for now we should just allow 4-byte larger
> than MTU TX packets, as long as the device is ethernet
> and can handle VLANs properly.
Incidently, I believe that this problem will only become more acute
and complex if support for 802.1ad (Provider Bridges, aka Q-in-Q),
802.1ah (Provider Backbone Bridges, aka MAC-in-MAC) or other standards
which further extend the maximum frame size.
Dave, you were mentioning to me the other day that the kernel
already supports some notion of Q-in-Q (though its not 802.1ad).
Does the current implementation allow for frames > 1504 bytes?
Is that a complication to the change proposed here?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] af_packet: account for VLAN when checking packet size
2010-10-22 8:41 ` Simon Horman
@ 2010-10-27 15:48 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2010-10-27 15:48 UTC (permalink / raw)
To: horms; +Cc: mst, eric.dumazet, netdev, johann.baudy
From: Simon Horman <horms@verge.net.au>
Date: Fri, 22 Oct 2010 10:41:26 +0200
> Incidently, I believe that this problem will only become more acute
> and complex if support for 802.1ad (Provider Bridges, aka Q-in-Q),
> 802.1ah (Provider Backbone Bridges, aka MAC-in-MAC) or other standards
> which further extend the maximum frame size.
No doubt.
> Dave, you were mentioning to me the other day that the kernel
> already supports some notion of Q-in-Q (though its not 802.1ad).
> Does the current implementation allow for frames > 1504 bytes?
It's only going to hardware offload and allow the extra space
for the outer-most VLAN tag. Everthing inside of the outer
tag will be handled in software as far as Linux is concerned.
> Is that a complication to the change proposed here?
For now, I don't think so.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-10-27 15:48 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-30 19:24 sending VLAN packets via packet_mmap Phil Sutter
2010-10-07 6:53 ` David Miller
2010-10-11 13:15 ` Phil Sutter
2010-10-11 13:25 ` [PATCH] af_packet: account for VLAN when checking packet size Phil Sutter
2010-10-11 14:03 ` Eric Dumazet
2010-10-11 16:01 ` David Miller
2010-10-11 17:29 ` Phil Sutter
2010-10-12 17:19 ` Michael S. Tsirkin
2010-10-12 17:40 ` David Miller
2010-10-22 8:41 ` Simon Horman
2010-10-27 15:48 ` David Miller
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).