Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4557278pxj; Wed, 12 May 2021 08:09:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyj47OiqmmljgRu7NU5w9M09XW3R5cKdYVZMOtJr1eWsuo7HYSl647u3kHHfHlI9b2+2ULy X-Received: by 2002:a05:6830:19e2:: with SMTP id t2mr31444390ott.190.1620832154609; Wed, 12 May 2021 08:09:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620832154; cv=none; d=google.com; s=arc-20160816; b=UWf57cKOrH1p61NKx768ggFaB1qxBw7x2HCERqEyK6W6pRVOU3A57LHGlCDTc/+SkH dQlObHECLnFqrOdQj5U19jtUIwUVw38lJLvwLmuVcQCgDLpw2BPOQDkjEH8H2tnNg8o4 zN3W5V4Zbg34/RtP6+cmRtzVmJIB2DupyyaNJ3OKF1rg0vVBa6bjO4xOGCF+EFxaDgHQ 5Rht2lPs5l35qFNY6jIlm2kM8TcftHnO91aDZrQkGPUwDael4A4Rh/M5OF6L9gbL/ugg oNI1b6dDIxjXBPwjSsvsQQVJfnDd8HIzyEVY8L3LpvtH41TYRXclYUSy4nmSOGuYT2Y/ o0iQ== 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=LUxoXoPIzmcY22QSb4F7PPh2xTEINGebiR/y6FmSFeA=; b=FL9M+t+y9uxuZwpj2maZzN2f/ohHUqO2RP81vfIp5QsZNTWxLazP2Wb6J1SpyiZQNc ddbcVg9UJuRMB9KbDSfPSuABf57jA82YIKC5i9WS79U4nOt4X7E+eJSywvI2xQXqUGLk xTfNc+1Ym0YwWVpus6zYYEI7aGKbJ7q2iHWhEaGOW2lWYwbIuZA1xtCUc2pPOtdAFvBG uiTSLTMOQ3ssOjjlJ7GPg5NWY4phKzXOn8XvSZypQO/7kBNJt5wNeyVzb2rafd2AGBeN WIWf6wQ0Z4x6d1kwy5btPglVQVkMYvm8AJuiIHFGahkRsl/mC6NNofBruxl83ijtWmnn SaLQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=LCFKgRJL; 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=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c16si146048otl.33.2021.05.12.08.09.01; Wed, 12 May 2021 08:09:14 -0700 (PDT) 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=@linuxfoundation.org header.s=korg header.b=LCFKgRJL; 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=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232870AbhELPGe (ORCPT + 99 others); Wed, 12 May 2021 11:06:34 -0400 Received: from mail.kernel.org ([198.145.29.99]:56304 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232959AbhELPC2 (ORCPT ); Wed, 12 May 2021 11:02:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5030C61628; Wed, 12 May 2021 14:58:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620831485; bh=3ZR0Kthvsr09WFNV8OS5pnAU4ozDeoiUk0gi7zgPe6k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LCFKgRJLD9U/vM91KuoAXk62JTWTFJB8y/NlTfls0m9IY4EMfmXLl5+o1sYolSqbH nATeYh+gcVWGgnIaDgYMd+BcZUWYp/+QPp+75N2OMHHMpOsQIzcyCuSu+n+u81fDlk gasXSzAzaplTniU7ugpC+bVA/yUIERnO2Dmo9KOk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Paul Durrant , Dongli Zhang , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Juergen Gross , Sasha Levin Subject: [PATCH 5.4 138/244] xen-blkback: fix compatibility bug with single page rings Date: Wed, 12 May 2021 16:48:29 +0200 Message-Id: <20210512144747.431395443@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144743.039977287@linuxfoundation.org> References: <20210512144743.039977287@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Paul Durrant [ Upstream commit d75e7f63b7c95c527cde42efb5d410d7f961498f ] Prior to commit 4a8c31a1c6f5 ("xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront"), the behaviour of xen-blkback when connecting to a frontend was: - read 'ring-page-order' - if not present then expect a single page ring specified by 'ring-ref' - else expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order This was correct behaviour, but was broken by the afforementioned commit to become: - read 'ring-page-order' - if not present then expect a single page ring (i.e. ring-page-order = 0) - expect a ring specified by 'ring-refX' where X is between 0 and 1 << ring-page-order - if that didn't work then see if there's a single page ring specified by 'ring-ref' This incorrect behaviour works most of the time but fails when a frontend that sets 'ring-page-order' is unloaded and replaced by one that does not because, instead of reading 'ring-ref', xen-blkback will read the stale 'ring-ref0' left around by the previous frontend will try to map the wrong grant reference. This patch restores the original behaviour. Fixes: 4a8c31a1c6f5 ("xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront") Signed-off-by: Paul Durrant Reviewed-by: Dongli Zhang Reviewed-by: "Roger Pau Monné" Link: https://lore.kernel.org/r/20210202175659.18452-1-paul@xen.org Signed-off-by: Juergen Gross Signed-off-by: Sasha Levin --- drivers/block/xen-blkback/common.h | 1 + drivers/block/xen-blkback/xenbus.c | 38 +++++++++++++----------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 1d3002d773f7..20cb0c23a22c 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -316,6 +316,7 @@ struct xen_blkif { struct work_struct free_work; unsigned int nr_ring_pages; + bool multi_ref; /* All rings for this device. */ struct xen_blkif_ring *rings; unsigned int nr_rings; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 040d7bb21397..dca91d641f1d 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -949,14 +949,17 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) for (i = 0; i < nr_grefs; i++) { char ring_ref_name[RINGREF_NAME_LEN]; - snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); + if (blkif->multi_ref) + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); + else { + WARN_ON(i != 0); + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref"); + } + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, "%u", &ring_ref[i]); if (err != 1) { - if (nr_grefs == 1) - break; - err = -EINVAL; xenbus_dev_fatal(dev, err, "reading %s/%s", dir, ring_ref_name); @@ -964,18 +967,6 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) } } - if (err != 1) { - WARN_ON(nr_grefs != 1); - - err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", - &ring_ref[0]); - if (err != 1) { - err = -EINVAL; - xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); - return err; - } - } - err = -ENOMEM; for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { req = kzalloc(sizeof(*req), GFP_KERNEL); @@ -1079,10 +1070,15 @@ static int connect_ring(struct backend_info *be) blkif->nr_rings, blkif->blk_protocol, protocol, pers_grants ? "persistent grants" : ""); - ring_page_order = xenbus_read_unsigned(dev->otherend, - "ring-page-order", 0); - - if (ring_page_order > xen_blkif_max_ring_order) { + err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", + &ring_page_order); + if (err != 1) { + blkif->nr_ring_pages = 1; + blkif->multi_ref = false; + } else if (ring_page_order <= xen_blkif_max_ring_order) { + blkif->nr_ring_pages = 1 << ring_page_order; + blkif->multi_ref = true; + } else { err = -EINVAL; xenbus_dev_fatal(dev, err, "requested ring page order %d exceed max:%d", @@ -1091,8 +1087,6 @@ static int connect_ring(struct backend_info *be) return err; } - blkif->nr_ring_pages = 1 << ring_page_order; - if (blkif->nr_rings == 1) return read_per_ring_refs(&blkif->rings[0], dev->otherend); else { -- 2.30.2