From patchwork Tue Apr 17 20:46:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Bj=C3=B8rn_Mork?= X-Patchwork-Id: 899664 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mork.no Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=mork.no header.i=@mork.no header.b="aPJcOpiA"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40Qck32qdTz9s1d for ; Wed, 18 Apr 2018 06:46:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752800AbeDQUqs (ORCPT ); Tue, 17 Apr 2018 16:46:48 -0400 Received: from canardo.mork.no ([148.122.252.1]:53643 "EHLO canardo.mork.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752387AbeDQUqr (ORCPT ); Tue, 17 Apr 2018 16:46:47 -0400 Received: from miraculix.mork.no (miraculix.mork.no [IPv6:2001:4641:0:2:7627:374e:db74:e353]) (authenticated bits=0) by canardo.mork.no (8.15.2/8.15.2) with ESMTPSA id w3HKkice002363 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 17 Apr 2018 22:46:44 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mork.no; s=b; t=1523998004; bh=G1ptGXD47dMbJjIe5jnwCnwTvSFKQeBhGEdGVD89F0c=; h=From:To:Cc:Subject:Date:Message-Id:From; b=aPJcOpiAUXHEkOazJQivtz6kFXtP3m7h9s4E1xd5dJthLAiN5HHJSSEiGzMLS6T/K kPWVudEB6vKS8JCeRnrParSbjaSKYvi35RDIPRmNAOU9Jpd8DQ/ZRtYTTySBinWkQi S3T+zzMzBP6MJJWffv3yFePtMYwGlnXOYQiJlTL8= Received: from bjorn by miraculix.mork.no with local (Exim 4.89) (envelope-from ) id 1f8XUx-000351-Rb; Tue, 17 Apr 2018 22:46:43 +0200 From: =?utf-8?q?Bj=C3=B8rn_Mork?= To: netdev@vger.kernel.org Cc: =?utf-8?q?Bj=C3=B8rn_Mork?= , Jason Wang Subject: [PATCH v3 net,stable] tun: fix vlan packet truncation Date: Tue, 17 Apr 2018 22:46:38 +0200 Message-Id: <20180417204638.11800-1-bjorn@mork.no> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.99.3 at canardo X-Virus-Status: Clean Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Bogus trimming in tun_net_xmit() causes truncated vlan packets. skb->len is correct whether or not skb_vlan_tag_present() is true. There is no more reason to adjust the skb length on xmit in this driver than any other driver. tun_put_user() adds 4 bytes to the total for tagged packets because it transmits the tag inline to userspace. This is similar to a nic transmitting the tag inline on the wire. Reproducing the bug by sending any tagged packet through back-to-back connected tap interfaces: socat TUN,tun-type=tap,iff-up,tun-name=in TUN,tun-type=tap,iff-up,tun-name=out & ip link add link in name in.20 type vlan id 20 ip addr add 10.9.9.9/24 dev in.20 ip link set in.20 up tshark -nxxi in -f arp -c1 2>/dev/null & tshark -nxxi out -f arp -c1 2>/dev/null & ping -c 1 10.9.9.5 >/dev/null 2>&1 The output from the 'in' and 'out' interfaces are different when the bug is present: Capturing on 'in' 0000 ff ff ff ff ff ff 76 cf 76 37 d5 0a 81 00 00 14 ......v.v7...... 0010 08 06 00 01 08 00 06 04 00 01 76 cf 76 37 d5 0a ..........v.v7.. 0020 0a 09 09 09 00 00 00 00 00 00 0a 09 09 05 .............. Capturing on 'out' 0000 ff ff ff ff ff ff 76 cf 76 37 d5 0a 81 00 00 14 ......v.v7...... 0010 08 06 00 01 08 00 06 04 00 01 76 cf 76 37 d5 0a ..........v.v7.. 0020 0a 09 09 09 00 00 00 00 00 00 .......... Fixes: aff3d70a07ff ("tun: allow to attach ebpf socket filter") Cc: Jason Wang Signed-off-by: Bjørn Mork Acked-by: Jason Wang --- v2: - Must still call pskb_trim() after running the filter, as pointed out by Jason and David. But no need to check if len < 0 anymore, since run_ebpf_filter() returns insigned ints. v3: - actually change the len <= 0 test as mentioned above drivers/net/tun.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 28583aa0c17d..ef33950a45d9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1102,12 +1102,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; len = run_ebpf_filter(tun, skb, len); - - /* Trim extra bytes since we may insert vlan proto & TCI - * in tun_put_user(). - */ - len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0; - if (len <= 0 || pskb_trim(skb, len)) + if (len == 0 || pskb_trim(skb, len)) goto drop; if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))