Apply XSA-155 patches (backends part)
This commit is contained in:
parent
8a88fa6b21
commit
06ce6989b0
@ -0,0 +1,57 @@
|
|||||||
|
From 4e2bc423e0cef0a42f93d989c0980301df1bd462 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Date: Fri, 30 Oct 2015 14:58:08 +0000
|
||||||
|
Subject: [PATCH 1/7] xen: Add RING_COPY_REQUEST()
|
||||||
|
|
||||||
|
Using RING_GET_REQUEST() on a shared ring is easy to use incorrectly
|
||||||
|
(i.e., by not considering that the other end may alter the data in the
|
||||||
|
shared ring while it is being inspected). Safe usage of a request
|
||||||
|
generally requires taking a local copy.
|
||||||
|
|
||||||
|
Provide a RING_COPY_REQUEST() macro to use instead of
|
||||||
|
RING_GET_REQUEST() and an open-coded memcpy(). This takes care of
|
||||||
|
ensuring that the copy is done correctly regardless of any possible
|
||||||
|
compiler optimizations.
|
||||||
|
|
||||||
|
Use a volatile source to prevent the compiler from reordering or
|
||||||
|
omitting the copy.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
v2: Update about GCC and bitfields.
|
||||||
|
---
|
||||||
|
include/xen/interface/io/ring.h | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
|
||||||
|
index 7d28aff..7dc685b 100644
|
||||||
|
--- a/include/xen/interface/io/ring.h
|
||||||
|
+++ b/include/xen/interface/io/ring.h
|
||||||
|
@@ -181,6 +181,20 @@ struct __name##_back_ring { \
|
||||||
|
#define RING_GET_REQUEST(_r, _idx) \
|
||||||
|
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Get a local copy of a request.
|
||||||
|
+ *
|
||||||
|
+ * Use this in preference to RING_GET_REQUEST() so all processing is
|
||||||
|
+ * done on a local copy that cannot be modified by the other end.
|
||||||
|
+ *
|
||||||
|
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
|
||||||
|
+ * to be ineffective where _req is a struct which consists of only bitfields.
|
||||||
|
+ */
|
||||||
|
+#define RING_COPY_REQUEST(_r, _idx, _req) do { \
|
||||||
|
+ /* Use volatile to force the copy into _req. */ \
|
||||||
|
+ *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
|
||||||
|
+} while (0)
|
||||||
|
+
|
||||||
|
#define RING_GET_RESPONSE(_r, _idx) \
|
||||||
|
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
|
||||||
|
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 100ac372a0e07ccc8c508c3884fa9020cfe08094 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Date: Fri, 30 Oct 2015 15:16:01 +0000
|
||||||
|
Subject: [PATCH 2/7] xen-netback: don't use last request to determine minimum
|
||||||
|
Tx credit
|
||||||
|
|
||||||
|
The last from guest transmitted request gives no indication about the
|
||||||
|
minimum amount of credit that the guest might need to send a packet
|
||||||
|
since the last packet might have been a small one.
|
||||||
|
|
||||||
|
Instead allow for the worst case 128 KiB packet.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/net/xen-netback/netback.c | 4 +---
|
||||||
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
|
||||||
|
index e481f37..b683581 100644
|
||||||
|
--- a/drivers/net/xen-netback/netback.c
|
||||||
|
+++ b/drivers/net/xen-netback/netback.c
|
||||||
|
@@ -679,9 +679,7 @@ static void tx_add_credit(struct xenvif_queue *queue)
|
||||||
|
* Allow a burst big enough to transmit a jumbo packet of up to 128kB.
|
||||||
|
* Otherwise the interface can seize up due to insufficient credit.
|
||||||
|
*/
|
||||||
|
- max_burst = RING_GET_REQUEST(&queue->tx, queue->tx.req_cons)->size;
|
||||||
|
- max_burst = min(max_burst, 131072UL);
|
||||||
|
- max_burst = max(max_burst, queue->credit_bytes);
|
||||||
|
+ max_burst = max(131072UL, queue->credit_bytes);
|
||||||
|
|
||||||
|
/* Take care that adding a new chunk of credit doesn't wrap to zero. */
|
||||||
|
max_credit = queue->remaining_credit + queue->credit_bytes;
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,131 @@
|
|||||||
|
From 4127e9ccae0eda622421d21132846abdf74f66ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Date: Fri, 30 Oct 2015 15:17:06 +0000
|
||||||
|
Subject: [PATCH 3/7] xen-netback: use RING_COPY_REQUEST() throughout
|
||||||
|
|
||||||
|
Instead of open-coding memcpy()s and directly accessing Tx and Rx
|
||||||
|
requests, use the new RING_COPY_REQUEST() that ensures the local copy
|
||||||
|
is correct.
|
||||||
|
|
||||||
|
This is more than is strictly necessary for guest Rx requests since
|
||||||
|
only the id and gref fields are used and it is harmless if the
|
||||||
|
frontend modifies these.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/net/xen-netback/netback.c | 30 ++++++++++++++----------------
|
||||||
|
1 file changed, 14 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
|
||||||
|
index b683581..1049c34 100644
|
||||||
|
--- a/drivers/net/xen-netback/netback.c
|
||||||
|
+++ b/drivers/net/xen-netback/netback.c
|
||||||
|
@@ -258,18 +258,18 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
|
||||||
|
struct netrx_pending_operations *npo)
|
||||||
|
{
|
||||||
|
struct xenvif_rx_meta *meta;
|
||||||
|
- struct xen_netif_rx_request *req;
|
||||||
|
+ struct xen_netif_rx_request req;
|
||||||
|
|
||||||
|
- req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
|
||||||
|
+ RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
|
||||||
|
|
||||||
|
meta = npo->meta + npo->meta_prod++;
|
||||||
|
meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
|
||||||
|
meta->gso_size = 0;
|
||||||
|
meta->size = 0;
|
||||||
|
- meta->id = req->id;
|
||||||
|
+ meta->id = req.id;
|
||||||
|
|
||||||
|
npo->copy_off = 0;
|
||||||
|
- npo->copy_gref = req->gref;
|
||||||
|
+ npo->copy_gref = req.gref;
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
@@ -424,7 +424,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
|
||||||
|
struct xenvif *vif = netdev_priv(skb->dev);
|
||||||
|
int nr_frags = skb_shinfo(skb)->nr_frags;
|
||||||
|
int i;
|
||||||
|
- struct xen_netif_rx_request *req;
|
||||||
|
+ struct xen_netif_rx_request req;
|
||||||
|
struct xenvif_rx_meta *meta;
|
||||||
|
unsigned char *data;
|
||||||
|
int head = 1;
|
||||||
|
@@ -443,15 +443,15 @@ static int xenvif_gop_skb(struct sk_buff *skb,
|
||||||
|
|
||||||
|
/* Set up a GSO prefix descriptor, if necessary */
|
||||||
|
if ((1 << gso_type) & vif->gso_prefix_mask) {
|
||||||
|
- req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
|
||||||
|
+ RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
|
||||||
|
meta = npo->meta + npo->meta_prod++;
|
||||||
|
meta->gso_type = gso_type;
|
||||||
|
meta->gso_size = skb_shinfo(skb)->gso_size;
|
||||||
|
meta->size = 0;
|
||||||
|
- meta->id = req->id;
|
||||||
|
+ meta->id = req.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
- req = RING_GET_REQUEST(&queue->rx, queue->rx.req_cons++);
|
||||||
|
+ RING_COPY_REQUEST(&queue->rx, queue->rx.req_cons++, &req);
|
||||||
|
meta = npo->meta + npo->meta_prod++;
|
||||||
|
|
||||||
|
if ((1 << gso_type) & vif->gso_mask) {
|
||||||
|
@@ -463,9 +463,9 @@ static int xenvif_gop_skb(struct sk_buff *skb,
|
||||||
|
}
|
||||||
|
|
||||||
|
meta->size = 0;
|
||||||
|
- meta->id = req->id;
|
||||||
|
+ meta->id = req.id;
|
||||||
|
npo->copy_off = 0;
|
||||||
|
- npo->copy_gref = req->gref;
|
||||||
|
+ npo->copy_gref = req.gref;
|
||||||
|
|
||||||
|
data = skb->data;
|
||||||
|
while (data < skb_tail_pointer(skb)) {
|
||||||
|
@@ -709,7 +709,7 @@ static void xenvif_tx_err(struct xenvif_queue *queue,
|
||||||
|
spin_unlock_irqrestore(&queue->response_lock, flags);
|
||||||
|
if (cons == end)
|
||||||
|
break;
|
||||||
|
- txp = RING_GET_REQUEST(&queue->tx, cons++);
|
||||||
|
+ RING_COPY_REQUEST(&queue->tx, cons++, txp);
|
||||||
|
} while (1);
|
||||||
|
queue->tx.req_cons = cons;
|
||||||
|
}
|
||||||
|
@@ -776,8 +776,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
|
||||||
|
if (drop_err)
|
||||||
|
txp = &dropped_tx;
|
||||||
|
|
||||||
|
- memcpy(txp, RING_GET_REQUEST(&queue->tx, cons + slots),
|
||||||
|
- sizeof(*txp));
|
||||||
|
+ RING_COPY_REQUEST(&queue->tx, cons + slots, txp);
|
||||||
|
|
||||||
|
/* If the guest submitted a frame >= 64 KiB then
|
||||||
|
* first->size overflowed and following slots will
|
||||||
|
@@ -1110,8 +1109,7 @@ static int xenvif_get_extras(struct xenvif_queue *queue,
|
||||||
|
return -EBADR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- memcpy(&extra, RING_GET_REQUEST(&queue->tx, cons),
|
||||||
|
- sizeof(extra));
|
||||||
|
+ RING_COPY_REQUEST(&queue->tx, cons, &extra);
|
||||||
|
if (unlikely(!extra.type ||
|
||||||
|
extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
|
||||||
|
queue->tx.req_cons = ++cons;
|
||||||
|
@@ -1320,7 +1318,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
|
||||||
|
|
||||||
|
idx = queue->tx.req_cons;
|
||||||
|
rmb(); /* Ensure that we see the request before we copy it. */
|
||||||
|
- memcpy(&txreq, RING_GET_REQUEST(&queue->tx, idx), sizeof(txreq));
|
||||||
|
+ RING_COPY_REQUEST(&queue->tx, idx, &txreq);
|
||||||
|
|
||||||
|
/* Credit-based scheduling. */
|
||||||
|
if (txreq.size > queue->remaining_credit &&
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
From 084b8c2e77f1ac07e4a3a121ff957c49a9379385 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com>
|
||||||
|
Date: Tue, 3 Nov 2015 16:34:09 +0000
|
||||||
|
Subject: [PATCH 4/7] xen-blkback: only read request operation from shared ring
|
||||||
|
once
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
A compiler may load a switch statement value multiple times, which could
|
||||||
|
be bad when the value is in memory shared with the frontend.
|
||||||
|
|
||||||
|
When converting a non-native request to a native one, ensure that
|
||||||
|
src->operation is only loaded once by using READ_ONCE().
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/block/xen-blkback/common.h | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
|
||||||
|
index 68e87a0..c929ae2 100644
|
||||||
|
--- a/drivers/block/xen-blkback/common.h
|
||||||
|
+++ b/drivers/block/xen-blkback/common.h
|
||||||
|
@@ -408,8 +408,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
|
||||||
|
struct blkif_x86_32_request *src)
|
||||||
|
{
|
||||||
|
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
|
||||||
|
- dst->operation = src->operation;
|
||||||
|
- switch (src->operation) {
|
||||||
|
+ dst->operation = READ_ONCE(src->operation);
|
||||||
|
+ switch (dst->operation) {
|
||||||
|
case BLKIF_OP_READ:
|
||||||
|
case BLKIF_OP_WRITE:
|
||||||
|
case BLKIF_OP_WRITE_BARRIER:
|
||||||
|
@@ -456,8 +456,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
|
||||||
|
struct blkif_x86_64_request *src)
|
||||||
|
{
|
||||||
|
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
|
||||||
|
- dst->operation = src->operation;
|
||||||
|
- switch (src->operation) {
|
||||||
|
+ dst->operation = READ_ONCE(src->operation);
|
||||||
|
+ switch (dst->operation) {
|
||||||
|
case BLKIF_OP_READ:
|
||||||
|
case BLKIF_OP_WRITE:
|
||||||
|
case BLKIF_OP_WRITE_BARRIER:
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
From 89739c14c72e5c1626a5cd5e09cbb2efeaadb6d8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Date: Mon, 16 Nov 2015 18:02:32 +0000
|
||||||
|
Subject: [PATCH 6/7] xen-scsiback: safely copy requests
|
||||||
|
|
||||||
|
The copy of the ring request was lacking a following barrier(),
|
||||||
|
potentially allowing the compiler to optimize the copy away.
|
||||||
|
|
||||||
|
Use RING_COPY_REQUEST() to ensure the request is copied to local
|
||||||
|
memory.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Reviewed-by: Juergen Gross <jgross@suse.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/xen/xen-scsiback.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
|
||||||
|
index 43bcae8..ad4eb10 100644
|
||||||
|
--- a/drivers/xen/xen-scsiback.c
|
||||||
|
+++ b/drivers/xen/xen-scsiback.c
|
||||||
|
@@ -726,7 +726,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
|
||||||
|
if (!pending_req)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
- ring_req = *RING_GET_REQUEST(ring, rc);
|
||||||
|
+ RING_COPY_REQUEST(ring, rc, &ring_req);
|
||||||
|
ring->req_cons = ++rc;
|
||||||
|
|
||||||
|
err = prepare_pending_reqs(info, &ring_req, pending_req);
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,81 @@
|
|||||||
|
From f6f4388c917ce96b075a239a4535b8efc6064d14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
Date: Mon, 16 Nov 2015 12:40:48 -0500
|
||||||
|
Subject: [PATCH 7/7] xen/pciback: Save xen_pci_op commands before processing
|
||||||
|
it
|
||||||
|
|
||||||
|
Double fetch vulnerabilities that happen when a variable is
|
||||||
|
fetched twice from shared memory but a security check is only
|
||||||
|
performed the first time.
|
||||||
|
|
||||||
|
The xen_pcibk_do_op function performs a switch statements on the op->cmd
|
||||||
|
value which is stored in shared memory. Interestingly this can result
|
||||||
|
in a double fetch vulnerability depending on the performed compiler
|
||||||
|
optimization.
|
||||||
|
|
||||||
|
This patch fixes it by saving the xen_pci_op command before
|
||||||
|
processing it. We also use 'barrier' to make sure that the
|
||||||
|
compiler does not perform any optimization.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
Signed-off-by: Jan Beulich <JBeulich@suse.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/xen/xen-pciback/pciback.h | 1 +
|
||||||
|
drivers/xen/xen-pciback/pciback_ops.c | 15 ++++++++++++++-
|
||||||
|
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
|
||||||
|
index 58e38d5..4d529f3 100644
|
||||||
|
--- a/drivers/xen/xen-pciback/pciback.h
|
||||||
|
+++ b/drivers/xen/xen-pciback/pciback.h
|
||||||
|
@@ -37,6 +37,7 @@ struct xen_pcibk_device {
|
||||||
|
struct xen_pci_sharedinfo *sh_info;
|
||||||
|
unsigned long flags;
|
||||||
|
struct work_struct op_work;
|
||||||
|
+ struct xen_pci_op op;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xen_pcibk_dev_data {
|
||||||
|
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
|
||||||
|
index c4a0666..a0e0e3e 100644
|
||||||
|
--- a/drivers/xen/xen-pciback/pciback_ops.c
|
||||||
|
+++ b/drivers/xen/xen-pciback/pciback_ops.c
|
||||||
|
@@ -298,9 +298,11 @@ void xen_pcibk_do_op(struct work_struct *data)
|
||||||
|
container_of(data, struct xen_pcibk_device, op_work);
|
||||||
|
struct pci_dev *dev;
|
||||||
|
struct xen_pcibk_dev_data *dev_data = NULL;
|
||||||
|
- struct xen_pci_op *op = &pdev->sh_info->op;
|
||||||
|
+ struct xen_pci_op *op = &pdev->op;
|
||||||
|
int test_intx = 0;
|
||||||
|
|
||||||
|
+ *op = pdev->sh_info->op;
|
||||||
|
+ barrier();
|
||||||
|
dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
|
||||||
|
|
||||||
|
if (dev == NULL)
|
||||||
|
@@ -342,6 +344,17 @@ void xen_pcibk_do_op(struct work_struct *data)
|
||||||
|
if ((dev_data->enable_intx != test_intx))
|
||||||
|
xen_pcibk_control_isr(dev, 0 /* no reset */);
|
||||||
|
}
|
||||||
|
+ pdev->sh_info->op.err = op->err;
|
||||||
|
+ pdev->sh_info->op.value = op->value;
|
||||||
|
+#ifdef CONFIG_PCI_MSI
|
||||||
|
+ if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
|
||||||
|
+ unsigned int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < op->value; i++)
|
||||||
|
+ pdev->sh_info->op.msix_entries[i].vector =
|
||||||
|
+ op->msix_entries[i].vector;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
/* Tell the driver domain that we're done. */
|
||||||
|
wmb();
|
||||||
|
clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
From d52f00960c1070c683809faddd35a2223e2b8a6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com>
|
||||||
|
Date: Tue, 3 Nov 2015 16:40:43 +0000
|
||||||
|
Subject: [PATCH 6/7] xen-blkback: read from indirect descriptors only once
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Since indirect descriptors are in memory shared with the frontend, the
|
||||||
|
frontend could alter the first_sect and last_sect values after they have
|
||||||
|
been validated but before they are recorded in the request. This may
|
||||||
|
result in I/O requests that overflow the foreign page, possibly
|
||||||
|
overwriting local pages when the I/O request is executed.
|
||||||
|
|
||||||
|
When parsing indirect descriptors, only read first_sect and last_sect
|
||||||
|
once.
|
||||||
|
|
||||||
|
This is part of XSA155.
|
||||||
|
|
||||||
|
CC: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
|
||||||
|
Signed-off-by: David Vrabel <david.vrabel@citrix.com>
|
||||||
|
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
----
|
||||||
|
v2: This is against v4.3
|
||||||
|
---
|
||||||
|
drivers/block/xen-blkback/blkback.c | 12 +++++++-----
|
||||||
|
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
|
||||||
|
index 6a685ae..f2e7a38 100644
|
||||||
|
--- a/drivers/block/xen-blkback/blkback.c
|
||||||
|
+++ b/drivers/block/xen-blkback/blkback.c
|
||||||
|
@@ -950,6 +950,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
|
||||||
|
goto unmap;
|
||||||
|
|
||||||
|
for (n = 0, i = 0; n < nseg; n++) {
|
||||||
|
+ uint8_t first_sect, last_sect;
|
||||||
|
+
|
||||||
|
if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
|
||||||
|
/* Map indirect segments */
|
||||||
|
if (segments)
|
||||||
|
@@ -958,14 +960,14 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
|
||||||
|
}
|
||||||
|
i = n % SEGS_PER_INDIRECT_FRAME;
|
||||||
|
pending_req->segments[n]->gref = segments[i].gref;
|
||||||
|
- seg[n].nsec = segments[i].last_sect -
|
||||||
|
- segments[i].first_sect + 1;
|
||||||
|
- seg[n].offset = (segments[i].first_sect << 9);
|
||||||
|
- if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
|
||||||
|
- (segments[i].last_sect < segments[i].first_sect)) {
|
||||||
|
+ first_sect = READ_ONCE(segments[i].first_sect);
|
||||||
|
+ last_sect = READ_ONCE(segments[i].last_sect);
|
||||||
|
+ if (last_sect >= (PAGE_SIZE >> 9) || last_sect < first_sect) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto unmap;
|
||||||
|
}
|
||||||
|
+ seg[n].nsec = last_sect - first_sect + 1;
|
||||||
|
+ seg[n].offset = first_sect << 9;
|
||||||
|
preq->nr_sects += seg[n].nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
10
series.conf
10
series.conf
@ -9,3 +9,13 @@ patches.xen/xen-netfront-detach-crash.patch
|
|||||||
#patches.xen/pvops-0100-usb-xen-pvusb-driver.patch
|
#patches.xen/pvops-0100-usb-xen-pvusb-driver.patch
|
||||||
patches.xen/pvops-blkfront-removable-flag.patch
|
patches.xen/pvops-blkfront-removable-flag.patch
|
||||||
patches.xen/pvops-blkfront-eject-support.patch
|
patches.xen/pvops-blkfront-eject-support.patch
|
||||||
|
|
||||||
|
# Security fixes
|
||||||
|
patches.xen/xsa155-linux-xsa155-0001-xen-Add-RING_COPY_REQUEST.patch
|
||||||
|
patches.xen/xsa155-linux-xsa155-0002-xen-netback-don-t-use-last-request-to-determine-mini.patch
|
||||||
|
patches.xen/xsa155-linux-xsa155-0003-xen-netback-use-RING_COPY_REQUEST-throughout.patch
|
||||||
|
patches.xen/xsa155-linux-xsa155-0004-xen-blkback-only-read-request-operation-from-shared-.patch
|
||||||
|
patches.xen/xsa155-linux43-0005-xen-blkback-read-from-indirect-descriptors-only-once.patch
|
||||||
|
patches.xen/xsa155-linux-xsa155-0006-xen-scsiback-safely-copy-requests.patch
|
||||||
|
patches.xen/xsa155-linux-xsa155-0007-xen-pciback-Save-xen_pci_op-commands-before-processi.patch
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user