From patchwork Sat Oct 22 20:30:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 101634 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp2257686qge; Sun, 23 Oct 2016 12:52:49 -0700 (PDT) X-Received: by 10.99.110.142 with SMTP id j136mr18086378pgc.132.1477252369197; Sun, 23 Oct 2016 12:52:49 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c3si10153491paw.162.2016.10.23.12.52.48; Sun, 23 Oct 2016 12:52:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-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 linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756714AbcJWTwo (ORCPT + 27 others); Sun, 23 Oct 2016 15:52:44 -0400 Received: from mout.kundenserver.de ([212.227.17.24]:62334 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754882AbcJWTwm (ORCPT ); Sun, 23 Oct 2016 15:52:42 -0400 Received: from wuerfel.localnet ([78.43.20.153]) by mrelayeu.kundenserver.de (mreue101) with ESMTPSA (Nemesis) id 0LdVp4-1ch7U70z2o-00incK; Sun, 23 Oct 2016 21:52:13 +0200 From: Arnd Bergmann To: Tom Herbert Cc: Jiri Pirko , "David S. Miller" , Alexander Duyck , Jiri Pirko , Hadar Hen Zion , Gao Feng , Amir Vadai , Linux Kernel Network Developers , LKML , Linus Torvalds Subject: [PATCH net-next] flow_dissector: fix vlan tag handling Date: Sat, 22 Oct 2016 22:30:08 +0200 Message-ID: <3590200.oN5tv3ZPpc@wuerfel> User-Agent: KMail/5.1.3 (Linux/4.4.0-34-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: References: <20161021155626.4020344-1-arnd@arndb.de> <20161022155752.GD26044@egarver> MIME-Version: 1.0 X-Provags-ID: V03:K0:Erveu3AVmOTuBWNUJsFsnfnyr4YWNF310OQsDtVuRIAHiCg6coS Ag/eP+HORyIR04PpItdasG/yIiNuPNQX7nWXF8TqhT5RafFvegk/jcHW3AcWjow/X42bzWg P1TSG+wb4vn7jJBy4zRCYRylypHals2w7+9aBDnSpOzdagtYvTycZ2Oc6eboWlvfzb2RGYo QZVuirrvxJ80Y/kS5nHaw== X-UI-Out-Filterresults: notjunk:1; V01:K0:CBdmLy1S4x0=:9jPdDnqF00Dqtk9lz8itX9 U6ayBIc1/0iVzmOzCktAMhJtfYcC6XHJxU8AR/JeUV9F2fH3tOauIbXpCXLh7rDSFxzLA0L21 dNWxRZXwQyDt91B9O2xb93vzrlHmhU/WHLyQ45IHIqk46fhTAYAeb6AmqfQ+hl8KKYPz6uUDo 5oZOMYkwU1K3s/kD4d3M/sj3liOMfkYyYYjcQ/bj0jXOrubxrNDxCxB8dJFcflTL20GaXnQj/ MoVeVC78LXoA4abRcflljKsRTqbCb7kpJas9gdG+yPaR0XZY1RS2uehlpqkX/Kkr0wwtQxWaS yF+3YBQHDzhj3pd8rrmwh5wAuegjttUVpYeYPno5YmAJjrUvbQJrp1d6YHqt/4xbxI4Hgekb2 ra+i0m8IP75TKb8e2tOP34l3AqwrfUx3cP3nCEVGm8fta5ADQ6ZEBJoqsPso1CseetwB16m2L 7N9J8VHDpMHYJItz4kGgxmJ8A2NIu0uSxV2DiFJTdgpI437vtzn6D9nEa2Ne0yqoxEMo3kUZd qQHd81EukVOSBEe6XNu7Nj2ONnxuvV6lQZiZV5TtYpUWbpRk28whBWzuIsLZbPppF/sXcFTZs R+ckpB65gKOTJH7+V0rnRpvfshwBP/lgYaOjDbfjLqAlsUTVlhDMz9WxBESJxwOF+7dWSu6zz ajL0PaO8HrT7HnEXzB+ftoiuOdLzDG6EXgITJsiVqmGaKZyEw0vTAY3Oa89a9T/fBfLraAw2p 4F8rk1mjmlMmtFHi Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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 as the stack may have been overwritten. 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.") Signed-off-by: Arnd Bergmann diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 44e6ba9d3a6b..17be1b66cc41 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -246,13 +246,10 @@ 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)) - 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 +267,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);