Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp1253338imw; Tue, 5 Jul 2022 06:29:07 -0700 (PDT) X-Google-Smtp-Source: AGRyM1s/PRaqkDffRPSHwtxbOE2B5415OBQoZlz94Na6tvcIbTG5t/kkf+iut2rqTgXgIyEVbN+B X-Received: by 2002:a63:69c9:0:b0:411:994d:1e12 with SMTP id e192-20020a6369c9000000b00411994d1e12mr25759135pgc.383.1657027747667; Tue, 05 Jul 2022 06:29:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657027747; cv=none; d=google.com; s=arc-20160816; b=gZcZoAIwRDR76v49/PVZp8l+ljMhL3I+mZzmiXA/vFCxKseClV1JBz/lAMbJ+rHqYf okwqcZbsQR6yqLfx2TkDO5bO7x6yLDSibQsRZoCD9Ifn7vICj/tDtDL5zBRkPK5Huyka T4yMWykudqAHjCGo+rZBeiSwsuyqX9YlukCZf26Fh45U/Asmc5i0vhYaVebFZ/wzmevg Xy6FQ+XZZGH06t1m++2eRw2Bttw/Sm+cfVQEomSrzWRoB2II1UAqdRauGhoGZJ3UNoE9 QWE4fFjM+oS5JaQGpl2epuytif6paMG1TvcwlSw4HOk4GRFc+vupQzrDjxzQDx0PUiu0 y7YA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=xb0G1HG5cWrJYqR07nHhN8cScZXoPCz4zm34i5qRBCs=; b=u9uBZVEGwLI43z3Rgh3I5uX+aHzFseV4zJipqwy4HGDYfzYc7WVvrhfDXfR8vtZEkX bjX5ONA86A/Q+1AhIHgLheNCu+7nKUDD6d3c1O6c0t+8pMg/SLW7iMfGNdhPrshakVlH iOQ8meRPCFP6FxJ6xKLrabJ7yQNQ/lZXl2kRkoARgqfNb9KFbR/1NKl4H59obiUAgFNL N1TfJg1uxJRThEPL1vtQJVqFg3DVqHzI/UJUoRDsfHsIhBmCJYsjA/EhPb8pnDnw9hHJ QLoVE2CKYXGos+cFPz4g7mbt/HrAHasTW3ZOyEyW7RVjku18YTaTOc+QSi/tykTx1U0n T9vg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=r8tNRXc7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g187-20020a636bc4000000b0040dfaf77438si24634139pgc.559.2022.07.05.06.28.55; Tue, 05 Jul 2022 06:29:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=r8tNRXc7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233386AbiGEMDL (ORCPT + 99 others); Tue, 5 Jul 2022 08:03:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230026AbiGEMBe (ORCPT ); Tue, 5 Jul 2022 08:01:34 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF09618375; Tue, 5 Jul 2022 05:01:33 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A1631B817D4; Tue, 5 Jul 2022 12:01:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E5485C341C7; Tue, 5 Jul 2022 12:01:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1657022491; bh=whB7DChqKjNXM6KulnnZB0EMSPHoC3atR9z0QHm4pT4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r8tNRXc7cFM/Qh5+bg584xm5qgRAFA6RM2fqZ8IX4DJTFrD5MGg/08/GsHkjVw337 ZhZWmdEI/wlWXouVX3SW62RISj9PLZtudoG1LmGZ7U9T0DnV/aIC34A3rO8OJEvsaM LE2FWOTb3WtCyWmU/062RhUoO2bcXIaONQdjlnys= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Juergen Gross Subject: [PATCH 4.14 25/29] xen/netfront: force data bouncing when backend is untrusted Date: Tue, 5 Jul 2022 13:58:13 +0200 Message-Id: <20220705115607.084848474@linuxfoundation.org> X-Mailer: git-send-email 2.37.0 In-Reply-To: <20220705115606.333669144@linuxfoundation.org> References: <20220705115606.333669144@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Roger Pau Monne commit 4491001c2e0fa69efbb748c96ec96b100a5cdb7e upstream. Bounce all data on the skbs to be transmitted into zeroed pages if the backend is untrusted. This avoids leaking data present in the pages shared with the backend but not part of the skb fragments. This requires introducing a new helper in order to allocate skbs with a size multiple of XEN_PAGE_SIZE so we don't leak contiguous data on the granted pages. Reporting whether the backend is to be trusted can be done using a module parameter, or from the xenstore frontend path as set by the toolstack when adding the device. This is CVE-2022-33741, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netfront.c | 50 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -63,6 +63,10 @@ module_param_named(max_queues, xennet_ma MODULE_PARM_DESC(max_queues, "Maximum number of queues per virtual interface"); +static bool __read_mostly xennet_trusted = true; +module_param_named(trusted, xennet_trusted, bool, 0644); +MODULE_PARM_DESC(trusted, "Is the backend trusted"); + #define XENNET_TIMEOUT (5 * HZ) static const struct ethtool_ops xennet_ethtool_ops; @@ -163,6 +167,9 @@ struct netfront_info { /* Is device behaving sane? */ bool broken; + /* Should skbs be bounced into a zeroed buffer? */ + bool bounce; + atomic_t rx_gso_checksum_fixup; }; @@ -592,6 +599,34 @@ static void xennet_mark_tx_pending(struc queue->tx_link[i] = TX_PENDING; } +struct sk_buff *bounce_skb(const struct sk_buff *skb) +{ + unsigned int headerlen = skb_headroom(skb); + /* Align size to allocate full pages and avoid contiguous data leaks */ + unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len, + XEN_PAGE_SIZE); + struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO); + + if (!n) + return NULL; + + if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) { + WARN_ONCE(1, "misaligned skb allocated\n"); + kfree_skb(n); + return NULL; + } + + /* Set the data pointer */ + skb_reserve(n, headerlen); + /* Set the tail pointer and length */ + skb_put(n, skb->len); + + BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len)); + + skb_copy_header(n, skb); + return n; +} + #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1) static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -644,9 +679,13 @@ static int xennet_start_xmit(struct sk_b /* The first req should be at least ETH_HLEN size or the packet will be * dropped by netback. + * + * If the backend is not trusted bounce all data to zeroed pages to + * avoid exposing contiguous data on the granted page not belonging to + * the skb. */ - if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) { - nskb = skb_copy(skb, GFP_ATOMIC); + if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) { + nskb = bounce_skb(skb); if (!nskb) goto drop; dev_consume_skb_any(skb); @@ -1946,6 +1985,10 @@ static int talk_to_netback(struct xenbus info->netdev->irq = 0; + /* Check if backend is trusted. */ + info->bounce = !xennet_trusted || + !xenbus_read_unsigned(dev->nodename, "trusted", 1); + /* Check if backend supports multiple queues */ max_queues = xenbus_read_unsigned(info->xbdev->otherend, "multi-queue-max-queues", 1); @@ -2099,6 +2142,9 @@ static int xennet_connect(struct net_dev err = talk_to_netback(np->xbdev, np); if (err) return err; + if (np->bounce) + dev_info(&np->xbdev->dev, + "bouncing transmitted data to zeroed pages\n"); /* talk_to_netback() sets the correct number of queues */ num_queues = dev->real_num_tx_queues;