public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Juergen Gross <jgross@suse.com>,
	Jan Beulich <jbeulich@suse.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.4 32/52] xen/netfront: dont trust the backend response data blindly
Date: Mon,  6 Dec 2021 15:56:16 +0100	[thread overview]
Message-ID: <20211206145548.974503615@linuxfoundation.org> (raw)
In-Reply-To: <20211206145547.892668902@linuxfoundation.org>

From: Juergen Gross <jgross@suse.com>

commit a884daa61a7d91650987e855464526aef219590f upstream.

Today netfront will trust the backend to send only sane response data.
In order to avoid privilege escalations or crashes in case of malicious
backends verify the data to be within expected limits. Especially make
sure that the response always references an outstanding request.

Note that only the tx queue needs special id handling, as for the rx
queue the id is equal to the index in the ring page.

Introduce a new indicator for the device whether it is broken and let
the device stop working when it is set. Set this indicator in case the
backend sets any weird data.


Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/xen-netfront.c |   80 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 75 insertions(+), 5 deletions(-)

--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -125,10 +125,12 @@ struct netfront_queue {
 	struct sk_buff *tx_skbs[NET_TX_RING_SIZE];
 	unsigned short tx_link[NET_TX_RING_SIZE];
 #define TX_LINK_NONE 0xffff
+#define TX_PENDING   0xfffe
 	grant_ref_t gref_tx_head;
 	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
 	struct page *grant_tx_page[NET_TX_RING_SIZE];
 	unsigned tx_skb_freelist;
+	unsigned int tx_pend_queue;
 
 	spinlock_t   rx_lock ____cacheline_aligned_in_smp;
 	struct xen_netif_rx_front_ring rx;
@@ -154,6 +156,9 @@ struct netfront_info {
 	struct netfront_stats __percpu *rx_stats;
 	struct netfront_stats __percpu *tx_stats;
 
+	/* Is device behaving sane? */
+	bool broken;
+
 	atomic_t rx_gso_checksum_fixup;
 };
 
@@ -338,7 +343,7 @@ static int xennet_open(struct net_device
 	unsigned int i = 0;
 	struct netfront_queue *queue = NULL;
 
-	if (!np->queues)
+	if (!np->queues || np->broken)
 		return -ENODEV;
 
 	for (i = 0; i < num_queues; ++i) {
@@ -365,11 +370,17 @@ static void xennet_tx_buf_gc(struct netf
 	RING_IDX cons, prod;
 	unsigned short id;
 	struct sk_buff *skb;
+	const struct device *dev = &queue->info->netdev->dev;
 
 	BUG_ON(!netif_carrier_ok(queue->info->netdev));
 
 	do {
 		prod = queue->tx.sring->rsp_prod;
+		if (RING_RESPONSE_PROD_OVERFLOW(&queue->tx, prod)) {
+			dev_alert(dev, "Illegal number of responses %u\n",
+				  prod - queue->tx.rsp_cons);
+			goto err;
+		}
 		rmb(); /* Ensure we see responses up to 'rp'. */
 
 		for (cons = queue->tx.rsp_cons; cons != prod; cons++) {
@@ -379,14 +390,27 @@ static void xennet_tx_buf_gc(struct netf
 			if (txrsp.status == XEN_NETIF_RSP_NULL)
 				continue;
 
-			id  = txrsp.id;
+			id = txrsp.id;
+			if (id >= RING_SIZE(&queue->tx)) {
+				dev_alert(dev,
+					  "Response has incorrect id (%u)\n",
+					  id);
+				goto err;
+			}
+			if (queue->tx_link[id] != TX_PENDING) {
+				dev_alert(dev,
+					  "Response for inactive request\n");
+				goto err;
+			}
+
+			queue->tx_link[id] = TX_LINK_NONE;
 			skb = queue->tx_skbs[id];
 			queue->tx_skbs[id] = NULL;
 			if (unlikely(gnttab_query_foreign_access(
 				queue->grant_tx_ref[id]) != 0)) {
-				pr_alert("%s: warning -- grant still in use by backend domain\n",
-					 __func__);
-				BUG();
+				dev_alert(dev,
+					  "Grant still in use by backend domain\n");
+				goto err;
 			}
 			gnttab_end_foreign_access_ref(
 				queue->grant_tx_ref[id], GNTMAP_readonly);
@@ -414,6 +438,12 @@ static void xennet_tx_buf_gc(struct netf
 	} while ((cons == prod) && (prod != queue->tx.sring->rsp_prod));
 
 	xennet_maybe_wake_tx(queue);
+
+	return;
+
+ err:
+	queue->info->broken = true;
+	dev_alert(dev, "Disabled for further use\n");
 }
 
 struct xennet_gnttab_make_txreq {
@@ -457,6 +487,12 @@ static void xennet_tx_setup_grant(unsign
 
 	*tx = info->tx_local;
 
+	/*
+	 * Put the request in the pending queue, it will be set to be pending
+	 * when the producer index is about to be raised.
+	 */
+	add_id_to_list(&queue->tx_pend_queue, queue->tx_link, id);
+
 	info->tx = tx;
 	info->size += info->tx_local.size;
 }
@@ -549,6 +585,15 @@ static u16 xennet_select_queue(struct ne
 	return queue_idx;
 }
 
+static void xennet_mark_tx_pending(struct netfront_queue *queue)
+{
+	unsigned int i;
+
+	while ((i = get_id_from_list(&queue->tx_pend_queue, queue->tx_link)) !=
+		TX_LINK_NONE)
+		queue->tx_link[i] = TX_PENDING;
+}
+
 #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
 
 static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -571,6 +616,8 @@ static int xennet_start_xmit(struct sk_b
 	/* Drop the packet if no queues are set up */
 	if (num_queues < 1)
 		goto drop;
+	if (unlikely(np->broken))
+		goto drop;
 	/* Determine which queue to transmit this SKB on */
 	queue_index = skb_get_queue_mapping(skb);
 	queue = &np->queues[queue_index];
@@ -660,6 +707,8 @@ static int xennet_start_xmit(struct sk_b
 	/* First request has the packet length. */
 	first_tx->size = skb->len;
 
+	xennet_mark_tx_pending(queue);
+
 	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify);
 	if (notify)
 		notify_remote_via_irq(queue->tx_irq);
@@ -984,6 +1033,13 @@ static int xennet_poll(struct napi_struc
 	skb_queue_head_init(&tmpq);
 
 	rp = queue->rx.sring->rsp_prod;
+	if (RING_RESPONSE_PROD_OVERFLOW(&queue->rx, rp)) {
+		dev_alert(&dev->dev, "Illegal number of responses %u\n",
+			  rp - queue->rx.rsp_cons);
+		queue->info->broken = true;
+		spin_unlock(&queue->rx_lock);
+		return 0;
+	}
 	rmb(); /* Ensure we see queued responses up to 'rp'. */
 
 	i = queue->rx.rsp_cons;
@@ -1224,6 +1280,9 @@ static irqreturn_t xennet_tx_interrupt(i
 	struct netfront_queue *queue = dev_id;
 	unsigned long flags;
 
+	if (queue->info->broken)
+		return IRQ_HANDLED;
+
 	spin_lock_irqsave(&queue->tx_lock, flags);
 	xennet_tx_buf_gc(queue);
 	spin_unlock_irqrestore(&queue->tx_lock, flags);
@@ -1236,6 +1295,9 @@ static irqreturn_t xennet_rx_interrupt(i
 	struct netfront_queue *queue = dev_id;
 	struct net_device *dev = queue->info->netdev;
 
+	if (queue->info->broken)
+		return IRQ_HANDLED;
+
 	if (likely(netif_carrier_ok(dev) &&
 		   RING_HAS_UNCONSUMED_RESPONSES(&queue->rx)))
 		napi_schedule(&queue->napi);
@@ -1257,6 +1319,10 @@ static void xennet_poll_controller(struc
 	struct netfront_info *info = netdev_priv(dev);
 	unsigned int num_queues = dev->real_num_tx_queues;
 	unsigned int i;
+
+	if (info->broken)
+		return;
+
 	for (i = 0; i < num_queues; ++i)
 		xennet_interrupt(0, &info->queues[i]);
 }
@@ -1627,6 +1693,7 @@ static int xennet_init_queue(struct netf
 
 	/* Initialise tx_skb_freelist as a free chain containing every entry. */
 	queue->tx_skb_freelist = 0;
+	queue->tx_pend_queue = TX_LINK_NONE;
 	for (i = 0; i < NET_TX_RING_SIZE; i++) {
 		queue->tx_link[i] = i + 1;
 		queue->grant_tx_ref[i] = GRANT_INVALID_REF;
@@ -1842,6 +1909,9 @@ static int talk_to_netback(struct xenbus
 	if (info->queues)
 		xennet_destroy_queues(info);
 
+	/* For the case of a reconnect reset the "broken" indicator. */
+	info->broken = false;
+
 	err = xennet_create_queues(info, &num_queues);
 	if (err < 0) {
 		xenbus_dev_fatal(dev, err, "creating queues");



  parent reply	other threads:[~2021-12-06 15:00 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-06 14:55 [PATCH 4.4 00/52] 4.4.294-rc1 review Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 01/52] staging: ion: Prevent incorrect reference counting behavour Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 02/52] USB: serial: option: add Telit LE910S1 0x9200 composition Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 03/52] USB: serial: option: add Fibocom FM101-GL variants Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 04/52] usb: hub: Fix usb enumeration issue due to address0 race Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 05/52] usb: hub: Fix locking issues with address0_mutex Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 06/52] binder: fix test regression due to sender_euid change Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 07/52] ALSA: ctxfi: Fix out-of-range access Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 08/52] staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect() Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 09/52] xen: dont continue xenstore initialization in case of errors Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 10/52] xen: detect uninitialized xenbus in xenbus_init Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 11/52] ARM: dts: BCM5301X: Add interrupt properties to GPIO node Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 12/52] ASoC: topology: Add missing rwsem around snd_ctl_remove() calls Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 13/52] net: ieee802154: handle iftypes as u32 Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 14/52] NFSv42: Dont fail clone() unless the OP_CLONE operation failed Greg Kroah-Hartman
2021-12-06 14:55 ` [PATCH 4.4 15/52] ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 16/52] scsi: mpt3sas: Fix kernel panic during drive powercycle test Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 17/52] tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited flows Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 18/52] tracing: Check pid filtering when creating events Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 19/52] hugetlbfs: flush TLBs correctly after huge_pmd_unshare Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 20/52] proc/vmcore: fix clearing user buffer by properly using clear_user() Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 21/52] NFC: add NCI_UNREG flag to eliminate the race Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 22/52] fuse: fix page stealing Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 23/52] fuse: release pipe buf after last use Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 24/52] shm: extend forced shm destroy to support objects from several IPC nses Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 25/52] xen: sync include/xen/interface/io/ring.h with Xens newest version Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 26/52] xen/blkfront: read response from backend only once Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 27/52] xen/blkfront: dont take local copy of a request from the ring page Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 28/52] xen/blkfront: dont trust the backend response data blindly Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 29/52] xen/netfront: read response from backend only once Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 30/52] xen/netfront: dont read data from request on the ring page Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 31/52] xen/netfront: disentangle tx_skb_freelist Greg Kroah-Hartman
2021-12-06 14:56 ` Greg Kroah-Hartman [this message]
2021-12-06 14:56 ` [PATCH 4.4 33/52] tty: hvc: replace BUG_ON() with negative return value Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 34/52] hugetlb: take PMD sharing into account when flushing tlb/caches Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 35/52] net: return correct error code Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 36/52] platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 37/52] s390/setup: avoid using memblock_enforce_memory_limit Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 38/52] scsi: iscsi: Unblock session then wake up error handler Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 39/52] net: tulip: de4x5: fix the problem that the array lp->phy[8] may be out of bound Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 40/52] net: ethernet: dec: tulip: de4x5: fix possible array overflows in type3_infoblock() Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 41/52] kprobes: Limit max data_size of the kretprobe instances Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 42/52] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 43/52] sata_fsl: fix warning in remove_proc_entry " Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 44/52] fs: add fget_many() and fput_many() Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 45/52] fget: check that the fd still exists after getting a ref to it Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 46/52] natsemi: xtensa: fix section mismatch warnings Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 47/52] net: qlogic: qlcnic: Fix a NULL pointer dereference in qlcnic_83xx_add_rings() Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 48/52] siphash: use _unaligned version by default Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 49/52] parisc: Fix "make install" on newer debian releases Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 50/52] vgacon: Propagate console boot parameters before calling `vc_resize Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 51/52] tty: serial: msm_serial: Deactivate RX DMA for polling support Greg Kroah-Hartman
2021-12-06 14:56 ` [PATCH 4.4 52/52] serial: pl011: Add ACPI SBSA UART match id Greg Kroah-Hartman
2021-12-06 19:34 ` [PATCH 4.4 00/52] 4.4.294-rc1 review Pavel Machek
2021-12-06 21:58 ` Shuah Khan
2021-12-07 20:39 ` Guenter Roeck
2021-12-08  4:15 ` Naresh Kamboju

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=20211206145548.974503615@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=davem@davemloft.net \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.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