Skip to content

Commit

Permalink
xen/blkfront: harden blkfront against event channel storms
Browse files Browse the repository at this point in the history
commit 0fd08a3 upstream.

The Xen blkfront driver is still vulnerable for an attack via excessive
number of events sent by the backend. Fix that by using lateeoi event
channels.

This is part of XSA-391

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
jgross1 authored and gregkh committed Dec 22, 2021
1 parent 76ec7fe commit 8ac3b6e
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions drivers/block/xen-blkfront.c
Expand Up @@ -1573,9 +1573,12 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
unsigned long flags;
struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id;
struct blkfront_info *info = rinfo->dev_info;
unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;

if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
return IRQ_HANDLED;
}

spin_lock_irqsave(&rinfo->ring_lock, flags);
again:
Expand All @@ -1591,6 +1594,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
unsigned long id;
unsigned int op;

eoiflag = 0;

RING_COPY_RESPONSE(&rinfo->ring, i, &bret);
id = bret.id;

Expand Down Expand Up @@ -1707,13 +1712,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)

spin_unlock_irqrestore(&rinfo->ring_lock, flags);

xen_irq_lateeoi(irq, eoiflag);

return IRQ_HANDLED;

err:
info->connected = BLKIF_STATE_ERROR;

spin_unlock_irqrestore(&rinfo->ring_lock, flags);

/* No EOI in order to avoid further interrupts. */

pr_alert("%s disabled for further use\n", info->gd->disk_name);
return IRQ_HANDLED;
}
Expand Down Expand Up @@ -1753,8 +1762,8 @@ static int setup_blkring(struct xenbus_device *dev,
if (err)
goto fail;

err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0,
"blkif", rinfo);
err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt,
0, "blkif", rinfo);
if (err <= 0) {
xenbus_dev_fatal(dev, err,
"bind_evtchn_to_irqhandler failed");
Expand Down

0 comments on commit 8ac3b6e

Please sign in to comment.