From patchwork Mon Oct 24 21:40:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 101612 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp2798981qge; Mon, 24 Oct 2016 14:41:17 -0700 (PDT) X-Received: by 10.98.18.23 with SMTP id a23mr32286769pfj.151.1477345277396; Mon, 24 Oct 2016 14:41:17 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g17si5260375pgh.51.2016.10.24.14.41.17; Mon, 24 Oct 2016 14:41:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757728AbcJXVlP (ORCPT + 4 others); Mon, 24 Oct 2016 17:41:15 -0400 Received: from mout.kundenserver.de ([212.227.17.24]:57447 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756713AbcJXVlN (ORCPT ); Mon, 24 Oct 2016 17:41:13 -0400 Received: from wuerfel.lan. ([78.43.20.153]) by mrelayeu.kundenserver.de (mreue104) with ESMTPA (Nemesis) id 0MabU1-1cENte0597-00K4mI; Mon, 24 Oct 2016 23:41:03 +0200 From: Arnd Bergmann To: "David S. Miller" Cc: Eric Garver , Hadar Hen Zion , Jiri Pirko , Arnd Bergmann , Alexander Duyck , Tom Herbert , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 net] flow_dissector: fix vlan tag handling Date: Mon, 24 Oct 2016 23:40:30 +0200 Message-Id: <20161024214058.1896091-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:7hd3XSloQlysGbfBfI/nmjRuG2OlFAVHnYCY2VPNvF/sXDe0W5c bcA87x7lVJexh2GJ15mlgyT/OeyO/v5C3OskL4z/tgfxaHUkT+wOZBPeptNt37zYLs2NM7T or0CGwnZim6Ij6ptC0vNfPqnzlPotQvO9KV++M/XsIC31bfNlPmlxVGT36GvWtkVy6/v4i7 K3oA6aFlK8XerDl8pyNUg== X-UI-Out-Filterresults: notjunk:1; V01:K0:dv6vsgdAcDk=:nUuswpITAkWQJuv3DK4BXd fEvCkPq9ioWAmWJolHo8LRtZ3VLcQZxLHoj6Dny1zXbfsBt7cqemW64UMsVcW8dG9m2Lc7iuG lQjxXOozEdyw6jU+TpD+gySF8fmoBWoY0LrMQKVgVTPM2hceSTNQt2xFCHXYRZn6JOR3rPk97 nqTSHyRlOP0yZ+i3lx249xakm+b+BgjDrLJ/HoXhjff8SWvX8gj0G7ZPYFNwSziqR+wzlwJSY ha1l4u99xF9fJkDYun3Ja38xfVDvWzjWn0057nG3FepjfOW6MhsatTSUVHTUUUrGJYp1ch6Y+ kdaj0qxIMtXbqxhGhdXg+uY05hZhwx4KUjzLCm9ergcaHiCxozNPH0Rx6supMJGNgHGNH09LZ 9BL5cKuLNAQiBSib9+JADcQYqvaKxuzKTNmnruTAGNmgiyFzDHKrnaYHaArRUMGzruXI7BxMY 01q2o1uESlGAz6vbvQNu+lo7FRYXW8Pnt2OSK3+nte2qyo1qNmaExIqxCxm6UzXiX9TvWH/wC WIxPL8pBrEogYnqhg+Fpn0KhG6qD03PloaP7Ap1bKetaJFSmCH4Acm0oUK2voib6ZCXSNaLW0 LoAu+AGSnq8HiHOL9Tfw/wKptqWpS7mZK26rDczzPkKsVQZZ6k5KwFN/Zm2cMnG5+5o67m/CT MQnFpZKJoozGvc3Uzcp1ps7RAZKelBm/GPOjrtcGumoQrRrYUeHdhgnfGLc59p0iCEUk= Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org gcc warns about an uninitialized pointer dereference in the vlan priority handling: net/core/flow_dissector.c: In function '__skb_flow_dissect': net/core/flow_dissector.c:281:61: error: 'vlan' may be used uninitialized in this function [-Werror=maybe-uninitialized] As pointed out by Jiri Pirko, the variable is never actually used without being initialized first as the only way it end up uninitialized is with skb_vlan_tag_present(skb)==true, and that means it does not get accessed. However, the warning hints at some related issues that I'm addressing here: - the second check for the vlan tag is different from the first one that tests the skb for being NULL first, causing both the warning and a possible NULL pointer dereference that was not entirely fixed. - The same patch that introduced the NULL pointer check dropped an earlier optimization that skipped the repeated check of the protocol type - The local '_vlan' variable is referenced through the 'vlan' pointer but the variable has gone out of scope by the time that it is accessed, causing undefined behavior Caching the result of the 'skb && skb_vlan_tag_present(skb)' check in a local variable allows the compiler to further optimize the later check. With those changes, the warning also disappears. Fixes: 3805a938a6c2 ("flow_dissector: Check skb for VLAN only if skb specified.") Fixes: d5709f7ab776 ("flow_dissector: For stripped vlan, get vlan info from skb->vlan_tci") Signed-off-by: Arnd Bergmann --- v3: set 'proto' variable correct again mark it for net, rather than net-next, as both patches that introduced the bugs are in mainline or in net/master v2: fix multiple issues found in the initial review beyond the uninitialized access that turned out to be ok net/core/flow_dissector.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) -- 2.9.0 diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 44e6ba9d3a6b..ab193e5def07 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -246,13 +246,13 @@ bool __skb_flow_dissect(const struct sk_buff *skb, case htons(ETH_P_8021AD): case htons(ETH_P_8021Q): { const struct vlan_hdr *vlan; + struct vlan_hdr _vlan; + bool vlan_tag_present = skb && skb_vlan_tag_present(skb); - if (skb && skb_vlan_tag_present(skb)) + if (vlan_tag_present) proto = skb->protocol; - if (eth_type_vlan(proto)) { - struct vlan_hdr _vlan; - + if (!vlan_tag_present || eth_type_vlan(skb->protocol)) { vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan); if (!vlan) @@ -270,7 +270,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, FLOW_DISSECTOR_KEY_VLAN, target_container); - if (skb_vlan_tag_present(skb)) { + if (vlan_tag_present) { key_vlan->vlan_id = skb_vlan_tag_get_id(skb); key_vlan->vlan_priority = (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT);