[3.13.y.z extended stable] Patch "openvswitch: fix panic with multiple vlan headers" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Fri Oct 31 20:53:20 UTC 2014

This is a note to let you know that I have just added a patch titled

    openvswitch: fix panic with multiple vlan headers

to the linux-3.13.y-queue branch of the 3.13.y.z extended stable tree 
which can be found at:


This patch is scheduled to be released in version

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.13.y.z tree, see



>From 05cd3928e26c5e9e4ebc623fd9733f6a55eb8550 Mon Sep 17 00:00:00 2001
From: Jiri Benc <jbenc at redhat.com>
Date: Thu, 21 Aug 2014 21:33:44 +0200
Subject: openvswitch: fix panic with multiple vlan headers

[ Upstream commit 2ba5af42a7b59ef01f9081234d8855140738defd ]

When there are multiple vlan headers present in a received frame, the first
one is put into vlan_tci and protocol is set to ETH_P_8021Q. Anything in the
skb beyond the VLAN TPID may be still non-linear, including the inner TCI
and ethertype. While ovs_flow_extract takes care of IP and IPv6 headers, it
does nothing with ETH_P_8021Q. Later, if OVS_ACTION_ATTR_POP_VLAN is
executed, __pop_vlan_tci pulls the next vlan header into vlan_tci.

This leads to two things:

1. Part of the resulting ethernet header is in the non-linear part of the
   skb. When eth_type_trans is called later as the result of
   OVS_ACTION_ATTR_OUTPUT, kernel BUGs in __skb_pull. Also, __pop_vlan_tci
   is in fact accessing random data when it reads past the TPID.

2. network_header points into the ethernet header instead of behind it.
   mac_len is set to a wrong value (10), too.

Reported-by: Yulong Pei <ypei at redhat.com>
Signed-off-by: Jiri Benc <jbenc at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
 net/openvswitch/actions.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 65cfaa8..07c4ae3 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -42,6 +42,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,

 static int make_writable(struct sk_buff *skb, int write_len)
+	if (!pskb_may_pull(skb, write_len))
+		return -ENOMEM;
 	if (!skb_cloned(skb) || skb_clone_writable(skb, write_len))
 		return 0;

@@ -70,6 +73,8 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)

 	vlan_set_encap_proto(skb, vhdr);
 	skb->mac_header += VLAN_HLEN;
+	if (skb_network_offset(skb) < ETH_HLEN)
+		skb_set_network_header(skb, ETH_HLEN);

 	return 0;

More information about the kernel-team mailing list