From patchwork Fri Feb 3 23:20:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 723964 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vFXt36Chdz9s4s for ; Sat, 4 Feb 2017 10:20:59 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ZY1Aj/eh"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752874AbdBCXU5 (ORCPT ); Fri, 3 Feb 2017 18:20:57 -0500 Received: from mail-qt0-f193.google.com ([209.85.216.193]:35825 "EHLO mail-qt0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752441AbdBCXU4 (ORCPT ); Fri, 3 Feb 2017 18:20:56 -0500 Received: by mail-qt0-f193.google.com with SMTP id s58so7660845qtc.2 for ; Fri, 03 Feb 2017 15:20:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NwCVkD1vwjGQ9QehLClvnL3cGiU4gezCmkDVRZLMeqc=; b=ZY1Aj/ehhaV8X3gznILtwDbJ41hNxY4Ynel+4xKxMaqSjuUa+AhUztehwd/OXamMXZ c2daMKweh4bns/DC2GeqPsVPgdGRCo06kYmOO4JuzdrPwQxkOESJZz9vtkz8psPOeWpf s/pb8/P6iaIoliTvpURSD8zaQZMPvuYBHE2CfbO2u7dAkDWvoq4NbVcxgI5J42eW1Cxm Yh06eFAE9PPCxue22V19hBOYJc/V87xslDILk7BS2U0+fqfD6N54tL7dYzYYkLmwgZde AV29MCaXHxga1OUogL+OGk/wMLbLlJvtVFBNl9WiWajgYewnv6khMGu+3yMdiXzh4AHk 5Imw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NwCVkD1vwjGQ9QehLClvnL3cGiU4gezCmkDVRZLMeqc=; b=a/qFjWCSrfZ4yVj6IMW8qSGjR10A+t5mJ4sUYF4mj90CjLuY1n0+I2Vu9pBfmshGRG b6mgjnAUWa/yA2yC2T2yZu4tEhe9XM5oFKf0/14s+2HwPpAYfLRtTNtzmSVOP9qgcdds 4V1rQ1hyIBqa5Jn31AenXMHFWJEb3REehhx0qttzTOfAr4VgQXHPsKdhllnv+UdyBDD0 WdwoIFckO7F5n7kIXU2224NynmDDQY2Q9Gefn7EkWy9hvct9p94uWPaS2JKsVMFDWQ7w UVsziuW4CDQCt97WEE/kLwSrwAtzJJWvNXI62GcPziccLku98hE3I51NN6DhinWLW29l WgVw== X-Gm-Message-State: AMke39mvXcHyZAfVXhiaqfBR2Z5TDZMQn2qTB3bk5jHnO600Tk2OcQUxZ68VbIK+cpBefw== X-Received: by 10.55.150.7 with SMTP id y7mr16078310qkd.232.1486164055719; Fri, 03 Feb 2017 15:20:55 -0800 (PST) Received: from willemb1.nyc.corp.google.com ([100.101.212.14]) by smtp.gmail.com with ESMTPSA id z8sm25814009qkz.42.2017.02.03.15.20.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Feb 2017 15:20:54 -0800 (PST) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, Willem de Bruijn , Eric Dumazet Subject: [PATCH net 1/2] tun: read vnet_hdr_sz once Date: Fri, 3 Feb 2017 18:20:48 -0500 Message-Id: <20170203232049.38982-2-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.11.0.483.g087da7b7c-goog In-Reply-To: <20170203232049.38982-1-willemdebruijn.kernel@gmail.com> References: <20170203232049.38982-1-willemdebruijn.kernel@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Willem de Bruijn When IFF_VNET_HDR is enabled, a virtio_net header must precede data. Data length is verified to be greater than or equal to expected header length tun->vnet_hdr_sz before copying. Read this value once and cache locally, as it can be updated between the test and use (TOCTOU). Signed-off-by: Willem de Bruijn Reported-by: Dmitry Vyukov CC: Eric Dumazet Acked-by: Eric Dumazet --- drivers/net/tun.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2cd10b26b650..bfabe180053e 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1170,9 +1170,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, } if (tun->flags & IFF_VNET_HDR) { - if (len < tun->vnet_hdr_sz) + int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz); + + if (len < vnet_hdr_sz) return -EINVAL; - len -= tun->vnet_hdr_sz; + len -= vnet_hdr_sz; if (!copy_from_iter_full(&gso, sizeof(gso), from)) return -EFAULT; @@ -1183,7 +1185,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, if (tun16_to_cpu(tun, gso.hdr_len) > len) return -EINVAL; - iov_iter_advance(from, tun->vnet_hdr_sz - sizeof(gso)); + iov_iter_advance(from, vnet_hdr_sz - sizeof(gso)); } if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) { @@ -1335,7 +1337,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, vlan_hlen = VLAN_HLEN; if (tun->flags & IFF_VNET_HDR) - vnet_hdr_sz = tun->vnet_hdr_sz; + vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz); total = skb->len + vlan_hlen + vnet_hdr_sz;