Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp7451274pxb; Thu, 18 Feb 2021 10:20:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJzjI9vCoVR36oPv/cOeZibWNB4Io2KlNWHgkGneYjfFzC2oNi5qK1kWFARTDu27ykSrf1Wb X-Received: by 2002:a17:906:6952:: with SMTP id c18mr800161ejs.233.1613672445637; Thu, 18 Feb 2021 10:20:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613672445; cv=none; d=google.com; s=arc-20160816; b=alShw0DhMKAjUUWtwOtXCaxQFO7yOiWTKTWm9BOlXHOM6Ed27aNlc4KeTvkEHH1XiC gxmz46uc+znMf7ht2Ub1FyxY3nK/dTWKW6Xg/Y5SEaGqIXwPCoxOvAqW2Xcq6PtqLaGO gst+rIwoufUdQ4y3MH0HRKYURQyQz+d7pKCYnTadDyLWCo5PvDMR39k4UBwIDPTfnDmM eJSNXDhcnWMNgeYLCL6kAA17/DLLMq1/sdmiiFYlPv42L+yDbDFc1EIyPfzIE+kVRE4w dn7Uui2zrXBe8rNsbGtcuugFaGFEgN5BEIVpGlM57mEoFlG6Mm7KKj8AtUp0GFCG/nh5 MQYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=vRWwBoukUWpf3kaTTQrlN4IVGff71cdIbdnfQeS/5Ko=; b=I64g2rnhzVxs/mycQ1tO8a7iMaWjd7Vi/klLo2vSYXziP30XEBaS0Mp5V0J7Qw3c+E 1EzqM0FkVVP/M7ATv/NJyuMtTXuYtmtiAIOJmuK5xzCoekb5ma28abNiMCFsDPtf3qVv 2lSmHEAv/AWsMEh9RN/Sm24+Qsfn7e9pxU1a+PdwO5i1TIGZzifkvru6JXQrdBlYkRil 4KZ3RtCUrO5WYQxM9ScdoFcOIp6vqWSRbp/hDbnil1hGXTvu7Q0UB2i3CshgaxJ/AzaE t1araGjhU+KOWyDmfeRXJ8Nk13+C7+Ld0Iix5qebrQ9eFDiR3bGXPXlRdmQHLdpqnO/q qQBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=ZVoi+oDt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id co9si3986322edb.555.2021.02.18.10.20.20; Thu, 18 Feb 2021 10:20:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=ZVoi+oDt; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232065AbhBRSR6 (ORCPT + 99 others); Thu, 18 Feb 2021 13:17:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232672AbhBRPwh (ORCPT ); Thu, 18 Feb 2021 10:52:37 -0500 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E727C061786 for ; Thu, 18 Feb 2021 07:51:18 -0800 (PST) Received: by mail-ej1-x636.google.com with SMTP id d8so6428440ejc.4 for ; Thu, 18 Feb 2021 07:51:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=vRWwBoukUWpf3kaTTQrlN4IVGff71cdIbdnfQeS/5Ko=; b=ZVoi+oDtUzlcdEftLSGeZhPJ2XfgGG18MLP6hZBH6xqL/SbYLgcIyQcpiW7B3eIVHg JTUcIBighF7XrK/6WhbfwshV0nZbSMWBiaUICBZhk3Zz6+RZ4mgQXDccbbV+Ow6Cca7x HPHX1sO/l0NCL0FBm5ZR3SVOcOtNa3KF4lq3tJX8OcmA4w7fxoo69WX2hWcOlOlwBIpV RM36Jnkn3ChZmluCRMIg0UHhZsykSrg5Uo4Ygwbd/nJYp9c3aBYyL544OtNbLVYi5oxD tlih6vyHpTm8EAkuDky1TDHxk5jpzgSpksejmXWGu07y959dgwi9LT3ZSSTET4WstBVK /stA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=vRWwBoukUWpf3kaTTQrlN4IVGff71cdIbdnfQeS/5Ko=; b=stNOZ027IZ7+oc2SKG2cLwhiStZVXPdnTBunozoLrv/slYTPEvHP/ReA8PC/4LI/4Q 6TiU8rV0pmgnYgbkj1LyChCpm9kSxeQeqkpwQ/upgYJ0jGtR3eFM1pKPQfrXm+rbFtlL TZ715u16BPrtxcBZStasR3K3x9K6azIc1j++Rsgjgq875fbVZFmZXvddvhiJVn31ZnQX RCZcOAHvmnVebpb7Z2ZPkzWDjTWOdF5iZbUB55/ePGt0eJSQFfqsO7g5/LRqEdTJCfK2 UxxtaP9EbXCnaN594V9T1crXt/cMuQl03qXkFwCv/yOkh2Va5L6Zu/wnFfIHPxJ/LPUQ jJFg== X-Gm-Message-State: AOAM532wQK+Pb6yccK3bIqBZxoEunQHfLbrgQ9c5wdgNjFXD5hRKiOXJ dvnmbPA2a8wzqarQi9lWjlECsDcPMyE= X-Received: by 2002:a17:907:da9:: with SMTP id go41mr4666596ejc.326.1613663476797; Thu, 18 Feb 2021 07:51:16 -0800 (PST) Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com. [209.85.221.42]) by smtp.gmail.com with ESMTPSA id o4sm2987319edw.78.2021.02.18.07.51.14 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 18 Feb 2021 07:51:15 -0800 (PST) Received: by mail-wr1-f42.google.com with SMTP id b3so3514414wrj.5 for ; Thu, 18 Feb 2021 07:51:14 -0800 (PST) X-Received: by 2002:a5d:4b84:: with SMTP id b4mr5020550wrt.50.1613663474248; Thu, 18 Feb 2021 07:51:14 -0800 (PST) MIME-Version: 1.0 References: <5e910d11a14da17c41317417fc41d3a9d472c6e7.1613659844.git.bnemeth@redhat.com> In-Reply-To: <5e910d11a14da17c41317417fc41d3a9d472c6e7.1613659844.git.bnemeth@redhat.com> From: Willem de Bruijn Date: Thu, 18 Feb 2021 10:50:37 -0500 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH] net: check if protocol extracted by virtio_net_hdr_set_proto is correct To: Balazs Nemeth Cc: Network Development , linux-kernel , "Michael S. Tsirkin" , Jason Wang , David Miller , virtualization@lists.linux-foundation.org Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Feb 18, 2021 at 10:01 AM Balazs Nemeth wrote: > > For gso packets, virtio_net_hdr_set_proto sets the protocol (if it isn't > set) based on the type in the virtio net hdr, but the skb could contain > anything since it could come from packet_snd through a raw socket. If > there is a mismatch between what virtio_net_hdr_set_proto sets and > the actual protocol, then the skb could be handled incorrectly later > on by gso. > > The network header of gso packets starts at 14 bytes, but a specially > crafted packet could fool the call to skb_flow_dissect_flow_keys_basic > as the network header offset in the skb could be incorrect. > Consequently, EINVAL is not returned. > > There are even packets that can cause an infinite loop. For example, a > packet with ethernet type ETH_P_MPLS_UC (which is unnoticed by > virtio_net_hdr_to_skb) that is sent to a geneve interface will be > handled by geneve_build_skb. In turn, it calls > udp_tunnel_handle_offloads which then calls skb_reset_inner_headers. > After that, the packet gets passed to mpls_gso_segment. That function > calculates the mpls header length by taking the difference between > network_header and inner_network_header. Since the two are equal > (due to the earlier call to skb_reset_inner_headers), it will calculate > a header of length 0, and it will not pull any headers. Then, it will > call skb_mac_gso_segment which will again call mpls_gso_segment, etc... > This leads to the infinite loop. > > For that reason, address the root cause of the issue: don't blindly > trust the information provided by the virtio net header. Instead, > check if the protocol in the packet actually matches the protocol set by > virtio_net_hdr_set_proto. > > Fixes: 9274124f023b ("net: stricter validation of untrusted gso packets") > Signed-off-by: Balazs Nemeth > --- > include/linux/virtio_net.h | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h > index e8a924eeea3d..cf2c53563f22 100644 > --- a/include/linux/virtio_net.h > +++ b/include/linux/virtio_net.h > @@ -79,8 +79,13 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, > if (gso_type && skb->network_header) { > struct flow_keys_basic keys; > > - if (!skb->protocol) > + if (!skb->protocol) { > + const struct ethhdr *eth = skb_eth_hdr(skb); > + Unfortunately, cannot assume that the device type is ARPHRD_ETHER. The underlying approach is sound: packets that have a gso type set in the virtio_net_hdr have to be IP packets. > virtio_net_hdr_set_proto(skb, hdr); > + if (skb->protocol != eth->h_proto) > + return -EINVAL; > + } > retry: > if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, > NULL, 0, 0, 0, > -- > 2.29.2 >