mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org,
	"Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com>,
	"Jan Beulich" <jbeulich@suse.com>
Subject: [33/84] xen/blkback: Check for insane amounts of request on the ring (v6).
Date: Wed, 31 Jul 2013 15:23:09 +0200	[thread overview]
Message-ID: <lsq.1375276989.446059173@decadent.org.uk> (raw)
In-Reply-To: <lsq.1375276989.251749228@decadent.org.uk>

3.2.50-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

commit 8e3f8755545cc4a7f4da8e9ef76d6d32e0dca576 upstream.

Check that the ring does not have an insane amount of requests
(more than there could fit on the ring).

If we detect this case we will stop processing the requests
and wait until the XenBus disconnects the ring.

The existing check RING_REQUEST_CONS_OVERFLOW which checks for how
many responses we have created in the past (rsp_prod_pvt) vs
requests consumed (req_cons) and whether said difference is greater or
equal to the size of the ring, does not catch this case.

Wha the condition does check if there is a need to process more
as we still have a backlog of responses to finish. Note that both
of those values (rsp_prod_pvt and req_cons) are not exposed on the
shared ring.

To understand this problem a mini crash course in ring protocol
response/request updates is in place.

There are four entries: req_prod and rsp_prod; req_event and rsp_event
to track the ring entries. We are only concerned about the first two -
which set the tone of this bug.

The req_prod is a value incremented by frontend for each request put
on the ring. Conversely the rsp_prod is a value incremented by the backend
for each response put on the ring (rsp_prod gets set by rsp_prod_pvt when
pushing the responses on the ring).  Both values can
wrap and are modulo the size of the ring (in block case that is 32).
Please see RING_GET_REQUEST and RING_GET_RESPONSE for the more details.

The culprit here is that if the difference between the
req_prod and req_cons is greater than the ring size we have a problem.
Fortunately for us, the '__do_block_io_op' loop:

	rc = blk_rings->common.req_cons;
	rp = blk_rings->common.sring->req_prod;

	while (rc != rp) {

		..
		blk_rings->common.req_cons = ++rc; /* before make_response() */

	}

will loop up to the point when rc == rp. The macros inside of the
loop (RING_GET_REQUEST) is smart and is indexing based on the modulo
of the ring size. If the frontend has provided a bogus req_prod value
we will loop until the 'rc == rp' - which means we could be processing
already processed requests (or responses) often.

The reason the RING_REQUEST_CONS_OVERFLOW is not helping here is
b/c it only tracks how many responses we have internally produced
and whether we would should process more. The astute reader will
notice that the macro RING_REQUEST_CONS_OVERFLOW provides two
arguments - more on this later.

For example, if we were to enter this function with these values:

       	blk_rings->common.sring->req_prod =  X+31415 (X is the value from
		the last time __do_block_io_op was called).
        blk_rings->common.req_cons = X
        blk_rings->common.rsp_prod_pvt = X

The RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, blk_rings->common.req_cons)
is doing:

	req_cons - rsp_prod_pvt >= 32

Which is,
	X - X >= 32 or 0 >= 32

And that is false, so we continue on looping (this bug).

If we re-use said macro RING_REQUEST_CONS_OVERFLOW and pass in the rp
instead (sring->req_prod) of rc, the this macro can do the check:

     req_prod - rsp_prov_pvt >= 32

Which is,
       X + 31415 - X >= 32 , or 31415 >= 32

which is true, so we can error out and break out of the function.

Unfortunatly the difference between rsp_prov_pvt and req_prod can be
at 32 (which would error out in the macro). This condition exists when
the backend is lagging behind with the responses and still has not finished
responding to all of them (so make_response has not been called), and
the rsp_prov_pvt + 32 == req_cons. This ends up with us not being able
to use said macro.

Hence introducing a new macro called RING_REQUEST_PROD_OVERFLOW which does
a simple check of:

    req_prod - rsp_prod_pvt > RING_SIZE

And with the X values from above:

   X + 31415 - X > 32

Returns true. Also not that if the ring is full (which is where
the RING_REQUEST_CONS_OVERFLOW triggered), we would not hit the
same condition:

   X + 32 - X > 32

Which is false.

Lets use that macro.
Note that in v5 of this patchset the macro was different - we used an
earlier version.

[v1: Move the check outside the loop]
[v2: Add a pr_warn as suggested by David]
[v3: Use RING_REQUEST_CONS_OVERFLOW as suggested by Jan]
[v4: Move wake_up after kthread_stop as suggested by Jan]
[v5: Use RING_REQUEST_PROD_OVERFLOW instead]
[v6: Use RING_REQUEST_PROD_OVERFLOW - Jan's version]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/block/xen-blkback/blkback.c | 13 ++++++++++++-
 drivers/block/xen-blkback/common.h  |  2 ++
 drivers/block/xen-blkback/xenbus.c  |  2 ++
 3 files changed, 16 insertions(+), 1 deletion(-)

--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -277,6 +277,7 @@ int xen_blkif_schedule(void *arg)
 {
 	struct xen_blkif *blkif = arg;
 	struct xen_vbd *vbd = &blkif->vbd;
+	int ret;
 
 	xen_blkif_get(blkif);
 
@@ -297,8 +298,12 @@ int xen_blkif_schedule(void *arg)
 		blkif->waiting_reqs = 0;
 		smp_mb(); /* clear flag *before* checking for work */
 
-		if (do_block_io_op(blkif))
+		ret = do_block_io_op(blkif);
+		if (ret > 0)
 			blkif->waiting_reqs = 1;
+		if (ret == -EACCES)
+			wait_event_interruptible(blkif->shutdown_wq,
+						 kthread_should_stop());
 
 		if (log_stats && time_after(jiffies, blkif->st_print))
 			print_stats(blkif);
@@ -539,6 +544,12 @@ __do_block_io_op(struct xen_blkif *blkif
 	rp = blk_rings->common.sring->req_prod;
 	rmb(); /* Ensure we see queued requests up to 'rp'. */
 
+	if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) {
+		rc = blk_rings->common.rsp_prod_pvt;
+		pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n",
+			rp, rc, rp - rc, blkif->vbd.pdevice);
+		return -EACCES;
+	}
 	while (rc != rp) {
 
 		if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -198,6 +198,8 @@ struct xen_blkif {
 	int			st_wr_sect;
 
 	wait_queue_head_t	waiting_to_free;
+	/* Thread shutdown wait queue. */
+	wait_queue_head_t	shutdown_wq;
 };
 
 
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -118,6 +118,7 @@ static struct xen_blkif *xen_blkif_alloc
 	atomic_set(&blkif->drain, 0);
 	blkif->st_print = jiffies;
 	init_waitqueue_head(&blkif->waiting_to_free);
+	init_waitqueue_head(&blkif->shutdown_wq);
 
 	return blkif;
 }
@@ -178,6 +179,7 @@ static void xen_blkif_disconnect(struct
 {
 	if (blkif->xenblkd) {
 		kthread_stop(blkif->xenblkd);
+		wake_up(&blkif->shutdown_wq);
 		blkif->xenblkd = NULL;
 	}
 


  parent reply	other threads:[~2013-07-31 13:26 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-31 13:23 [00/84] 3.2.50-rc1 review Ben Hutchings
2013-07-31 13:23 ` [37/84] ext4: don't allow ext4_free_blocks() to fail due to ENOMEM Ben Hutchings
2013-07-31 13:23 ` [32/84] xen/io/ring.h: new macro to detect whether there are too many requests on the ring Ben Hutchings
2013-07-31 13:23 ` [38/84] ACPI / memhotplug: Fix a stale pointer in error path Ben Hutchings
2013-07-31 13:23 ` [54/84] Btrfs: fix lock leak when resuming snapshot deletion Ben Hutchings
2013-07-31 13:23 ` [36/84] lockd: protect nlm_blocked access in nlmsvc_retry_blocked Ben Hutchings
2013-07-31 13:23 ` [70/84] USB: option: add D-Link DWM-152/C1 and DWM-156/C1 Ben Hutchings
2013-07-31 13:23 ` [01/84] bridge: fix switched interval for MLD Query types Ben Hutchings
2013-07-31 13:23 ` [44/84] ASoC: max98088 - fix element type of the register cache Ben Hutchings
2013-07-31 13:23 ` [42/84] ALSA: atiixp: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [72/84] staging: comedi: fix a race between do_cmd_ioctl() and read/write Ben Hutchings
2013-07-31 13:23 ` [41/84] ALSA: asihpi: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [04/84] ipv6: ip6_sk_dst_check() must not assume ipv6 dst Ben Hutchings
2013-07-31 13:23 ` [66/84] [SCSI] isci: Fix a race condition in the SSP task management path Ben Hutchings
2013-07-31 13:23 ` [74/84] powerpc/modules: Module CRC relocation fix causes perf issues Ben Hutchings
2013-07-31 13:23 ` [45/84] ALSA: ua101: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [79/84] xhci: fix null pointer dereference on ring_doorbell_for_active_rings Ben Hutchings
2013-07-31 13:23 ` [05/84] af_key: fix info leaks in notify messages Ben Hutchings
2013-07-31 13:23 ` [02/84] ipv6: don't call addrconf_dst_alloc again when enable lo Ben Hutchings
2013-07-31 13:23 ` [26/84] ARM: OMAP: RX-51: change probe order of touchscreen and panel SPI devices Ben Hutchings
2013-08-01  5:49   ` Tomi Valkeinen
2013-08-01  9:32     ` Ben Hutchings
2013-08-02 20:14       ` Ben Hutchings
2013-07-31 13:23 ` [64/84] drm/radeon: improve dac adjust heuristics for legacy pdac Ben Hutchings
2013-07-31 13:23 ` [84/84] usb: Clear both buffers when clearing a control transfer TT buffer Ben Hutchings
2013-07-31 13:23 ` [83/84] USB: mos7840: fix memory leak in open Ben Hutchings
2013-07-31 13:23 ` [40/84] usb: dwc3: fix wrong bit mask in dwc3_event_type Ben Hutchings
2013-07-31 13:23 ` [35/84] ASoC: sglt5000: Fix SGTL5000_PLL_FRAC_DIV_MASK Ben Hutchings
2013-07-31 13:23 ` [29/84] [SCSI] Fix incorrect memset in bnx2fc_parse_fcp_rsp Ben Hutchings
2013-07-31 13:23 ` [50/84] ALSA: hda - Add new GPU codec ID to snd-hda Ben Hutchings
2013-07-31 13:23 ` [12/84] ipv6: call udp_push_pending_frames when uncorking a socket with AF_INET pending data Ben Hutchings
2013-07-31 13:23 ` [17/84] 9p: fix off by one causing access violations and memory corruption Ben Hutchings
2013-07-31 13:23 ` [51/84] ALSA: hda - Add new GPU codec ID to snd-hda Ben Hutchings
2013-07-31 13:23 ` [10/84] ipv6,mcast: always hold idev->lock before mca_lock Ben Hutchings
2013-07-31 13:23 ` [52/84] ata: Fix DVD not dectected at some platform with Wellsburg PCH Ben Hutchings
2013-07-31 13:23 ` [75/84] USB: ti_usb_3410_5052: fix dynamic-id matching Ben Hutchings
2013-07-31 13:23 ` [78/84] usb: host: xhci: Enable XHCI_SPURIOUS_SUCCESS for all controllers with xhci 1.0 Ben Hutchings
2013-07-31 13:23 ` [77/84] xhci: Avoid NULL pointer deref when host dies Ben Hutchings
2013-07-31 13:23 ` [73/84] usb: option: add TP-LINK MA260 Ben Hutchings
2013-07-31 13:23 ` [49/84] staging: line6: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [30/84] fanotify: info leak in copy_event_to_user() Ben Hutchings
2013-07-31 13:23 ` [03/84] macvtap: fix recovery from gup errors Ben Hutchings
2013-07-31 13:23 ` [39/84] usb: dwc3: gadget: don't prevent gadget from being probed if we fail Ben Hutchings
2013-07-31 13:23 ` [07/84] neighbour: fix a race in neigh_destroy() Ben Hutchings
2013-07-31 13:23 ` [71/84] staging: comedi: COMEDI_CANCEL ioctl should wake up read/write Ben Hutchings
2013-07-31 13:23 ` [48/84] ASoC: s6000: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [56/84] ALSA: usb-audio: 6fire: return correct XRUN indication Ben Hutchings
2013-07-31 13:23 ` [21/84] atl1e: unmap partially mapped skb on dma error and free skb Ben Hutchings
2013-07-31 13:23 ` [65/84] drm/radeon: fix combios tables on older cards Ben Hutchings
2013-07-31 13:23 ` [25/84] sparc: tsb must be flushed before tlb Ben Hutchings
2013-07-31 13:23 ` [13/84] ipv6: ip6_append_data_mtu did not care about pmtudisc and frag_size Ben Hutchings
2013-07-31 13:23 ` [18/84] dummy: fix oops when loading the dummy failed Ben Hutchings
2013-07-31 13:23 ` [68/84] [SCSI] sd: fix crash when UA received on DIF enabled device Ben Hutchings
2013-07-31 13:23 ` [20/84] atl1e: fix dma mapping warnings Ben Hutchings
2013-07-31 13:23 ` Ben Hutchings [this message]
2013-07-31 13:23 ` [55/84] Btrfs: re-add root to dead root list if we stop dropping it Ben Hutchings
2013-07-31 13:23 ` [11/84] l2tp: add missing .owner to struct pppox_proto Ben Hutchings
2013-07-31 13:23 ` [43/84] ALSA: 6fire: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [28/84] virtio_net: fix race in RX VQ processing Ben Hutchings
2013-07-31 13:23 ` [23/84] sparc32: vm_area_struct access for old Sun SPARCs Ben Hutchings
2013-07-31 13:23 ` [62/84] USB: cp210x: add MMB and PI ZigBee USB Device Support Ben Hutchings
2013-07-31 13:23 ` [15/84] ifb: fix rcu_sched self-detected stalls Ben Hutchings
2013-07-31 13:23 ` [06/84] sh_eth: fix unhandled RFE interrupt Ben Hutchings
2013-07-31 13:23 ` [31/84] tracing: Use current_uid() for critical time tracing Ben Hutchings
2013-07-31 13:23 ` [08/84] x25: Fix broken locking in ioctl error paths Ben Hutchings
2013-07-31 13:23 ` [53/84] ACPI / video: ignore BIOS initial backlight value for Fujitsu E753 Ben Hutchings
2013-08-02 13:46   ` Luis Henriques
2013-08-02 14:24     ` Ben Hutchings
2013-07-31 13:23 ` [16/84] macvtap: correctly linearize skb when zerocopy is used Ben Hutchings
2013-07-31 13:23 ` [60/84] USB: option: append Petatel NP10T device to GSM modems list Ben Hutchings
2013-07-31 13:23 ` [46/84] ALSA: usx2y: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [58/84] USB: storage: Add MicroVault Flash Drive to unusual_devs Ben Hutchings
2013-07-31 13:23 ` [59/84] USB: misc: Add Manhattan Hi-Speed USB DVI Converter to sisusbvga Ben Hutchings
2013-07-31 13:23 ` [19/84] ifb: fix oops when loading the ifb failed Ben Hutchings
2013-07-31 13:23 ` [24/84] sparc64 address-congruence property Ben Hutchings
2013-07-31 13:23 ` [81/84] usb: serial: option: add Olivetti Olicard 200 Ben Hutchings
2013-07-31 13:23 ` [63/84] drm/radeon: Another card with wrong primary dac adj Ben Hutchings
2013-07-31 13:23 ` [67/84] [SCSI] qla2xxx: Properly set the tagging for commands Ben Hutchings
2013-07-31 13:23 ` [22/84] vlan: fix a race in egress prio management Ben Hutchings
2013-07-31 13:23 ` [80/84] usb: serial: option: blacklist ONDA MT689DC QMI interface Ben Hutchings
2013-07-31 13:23 ` [27/84] virtio: support unlocked queue poll Ben Hutchings
2013-07-31 13:23 ` [61/84] usb: cp210x support SEL C662 Vendor/Device Ben Hutchings
2013-07-31 13:23 ` [34/84] ASoC: sglt5000: Fix the default value of CHIP_SSS_CTRL Ben Hutchings
2013-07-31 13:23 ` [57/84] usb: serial: cp210x: Add USB ID for Netgear Switches embedded serial adapter Ben Hutchings
2013-07-31 13:23 ` [69/84] nfsd: nfsd_open: when dentry_open returns an error do not propagate as struct file Ben Hutchings
2013-07-31 13:23 ` [82/84] usb: serial: option.c: remove ONDA MT825UP product ID fromdriver Ben Hutchings
2013-07-31 13:23 ` [09/84] net: Swap ver and type in pppoe_hdr Ben Hutchings
2013-07-31 13:23 ` [47/84] ALSA: pxa2xx: Fix unlocked snd_pcm_stop() call Ben Hutchings
2013-07-31 13:23 ` [14/84] sunvnet: vnet_port_remove must call unregister_netdev Ben Hutchings
2013-07-31 13:23 ` [76/84] usb: serial: option: Add ONYX 3G device support Ben Hutchings
2013-08-01  9:30 ` [00/84] 3.2.50-rc1 review Ben Hutchings

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=lsq.1375276989.446059173@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=jbeulich@suse.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome