All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Durrant <xadimgnik@gmail.com>
To: "'Dongli Zhang'" <dongli.zhang@oracle.com>,
	<xen-devel@lists.xenproject.org>, <linux-block@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Cc: "'Paul Durrant'" <pdurrant@amazon.com>,
	"'Konrad Rzeszutek Wilk'" <konrad.wilk@oracle.com>,
	"'Roger Pau Monné'" <roger.pau@citrix.com>,
	"'Jens Axboe'" <axboe@kernel.dk>
Subject: RE: [PATCH] xen-blkback: fix compatibility bug with single page rings
Date: Thu, 28 Jan 2021 08:30:48 -0000	[thread overview]
Message-ID: <028b01d6f54f$e1e52280$a5af6780$@xen.org> (raw)
In-Reply-To: <18c3efc4-57b6-5a5d-cfa3-7820b7f5080c@oracle.com>

> -----Original Message-----
> From: Xen-devel <xen-devel-bounces@lists.xenproject.org> On Behalf Of Dongli Zhang
> Sent: 27 January 2021 19:57
> To: Paul Durrant <paul@xen.org>; xen-devel@lists.xenproject.org; linux-block@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Cc: Paul Durrant <pdurrant@amazon.com>; Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>; Roger Pau
> Monné <roger.pau@citrix.com>; Jens Axboe <axboe@kernel.dk>
> Subject: Re: [PATCH] xen-blkback: fix compatibility bug with single page rings
> 
> 
> 
> On 1/27/21 2:30 AM, Paul Durrant wrote:
> > From: Paul Durrant <pdurrant@amazon.com>
> >
> > 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
> > - 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 <pdurrant@amazon.com>
> > ---
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: "Roger Pau Monné" <roger.pau@citrix.com>
> > Cc: Jens Axboe <axboe@kernel.dk>
> > Cc: Dongli Zhang <dongli.zhang@oracle.com>
> > ---
> >  drivers/block/xen-blkback/common.h |  1 +
> >  drivers/block/xen-blkback/xenbus.c | 36 +++++++++++++-----------------
> >  2 files changed, 17 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
> > index b0c71d3a81a0..524a79f10de6 100644
> > --- a/drivers/block/xen-blkback/common.h
> > +++ b/drivers/block/xen-blkback/common.h
> > @@ -313,6 +313,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 9860d4842f36..4c1541cde68c 100644
> > --- a/drivers/block/xen-blkback/xenbus.c
> > +++ b/drivers/block/xen-blkback/xenbus.c
> > @@ -998,10 +998,15 @@ 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;
> 
> I think we should not simply break here because the failure can be due to when
> (nr_grefs == 1) and reading from legacy "ring-ref".
> 

Yes, you're quite right. This special case is no longer correct.

> Should we do something as below?
> 
> err = -EINVAL;
> xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir);
> return err;
> 

I think simply removing the 'if (nr_grefs == 1)' will be sufficient.

  Paul

> Dongli Zhang
> 
> 
> > @@ -1013,18 +1018,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);
> > @@ -1129,10 +1122,15 @@ static int connect_ring(struct backend_info *be)
> >  		 blkif->nr_rings, blkif->blk_protocol, protocol,
> >  		 blkif->vbd.feature_gnt_persistent ? "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",
> > @@ -1141,8 +1139,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 {
> >



  reply	other threads:[~2021-01-28  8:31 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-27 10:30 [PATCH] xen-blkback: fix compatibility bug with single page rings Paul Durrant
2021-01-27 10:56 ` Jan Beulich
2021-01-27 11:09   ` Paul Durrant
2021-01-27 11:20     ` Jan Beulich
2021-01-27 11:33       ` Paul Durrant
2021-01-27 11:37         ` Jan Beulich
2021-01-27 19:57 ` Dongli Zhang
2021-01-28  8:30   ` Paul Durrant [this message]
  -- strict thread matches above, loose matches on Subject: below --
2021-01-28 12:55 Paul Durrant
2021-01-28 13:04 ` Paul Durrant

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='028b01d6f54f$e1e52280$a5af6780$@xen.org' \
    --to=xadimgnik@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=dongli.zhang@oracle.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paul@xen.org \
    --cc=pdurrant@amazon.com \
    --cc=roger.pau@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.