From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, xen-devel@lists.xensource.com,
Jan Beulich <jbeulich@suse.com>,
Stefano.Stabellini@eu.citrix.com
Subject: [Qemu-devel] [PULL 11/11] xen/pt: unknown PCI config space fields should be read-only
Date: Tue, 2 Jun 2015 16:40:28 +0100 [thread overview]
Message-ID: <1433259628-4611-11-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1506021633010.19838@kaball.uk.xensource.com>
From: Jan Beulich <jbeulich@suse.com>
... by default. Add a per-device "permissive" mode similar to pciback's
to allow restoring previous behavior (and hence break security again,
i.e. should be used only for trusted guests).
This is part of XSA-131.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>)
---
hw/xen/xen_pt.c | 32 +++++++++++++++++++++++++++++---
hw/xen/xen_pt.h | 2 ++
hw/xen/xen_pt_config_init.c | 4 ++++
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 8923582..9afcda8 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -239,6 +239,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
XenPTReg *reg_entry = NULL;
uint32_t find_addr = addr;
XenPTRegInfo *reg = NULL;
+ bool wp_flag = false;
if (xen_pt_pci_config_access_check(d, addr, len)) {
return;
@@ -278,6 +279,10 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
/* pass directly to the real device for passthrough type register group */
if (reg_grp_entry == NULL) {
+ if (!s->permissive) {
+ wb_mask = 0;
+ wp_flag = true;
+ }
goto out;
}
@@ -298,12 +303,15 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
uint8_t *ptr_val = NULL;
+ uint32_t wp_mask = reg->emu_mask | reg->ro_mask;
valid_mask <<= (find_addr - real_offset) << 3;
ptr_val = (uint8_t *)&val + (real_offset & 3);
- if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
- wb_mask &= ~((reg->emu_mask
- >> ((find_addr - real_offset) << 3))
+ if (!s->permissive) {
+ wp_mask |= reg->res_mask;
+ }
+ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
+ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3))
<< ((len - emul_len) << 3));
}
@@ -347,6 +355,16 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
} else {
/* nothing to do with passthrough type register,
* continue to find next byte */
+ if (!s->permissive) {
+ wb_mask &= ~(0xff << ((len - emul_len) << 3));
+ /* Unused BARs will make it here, but we don't want to issue
+ * warnings for writes to them (bogus writes get dealt with
+ * above).
+ */
+ if (index < 0) {
+ wp_flag = true;
+ }
+ }
emul_len--;
find_addr++;
}
@@ -358,6 +376,13 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
memory_region_transaction_commit();
out:
+ if (wp_flag && !s->permissive_warned) {
+ s->permissive_warned = true;
+ xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n",
+ addr, len * 2, wb_mask);
+ xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n");
+ xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n");
+ }
for (index = 0; wb_mask; index += len) {
/* unknown regs are passed through */
while (!(wb_mask & 0xff)) {
@@ -824,6 +849,7 @@ static void xen_pt_unregister_device(PCIDevice *d)
static Property xen_pci_passthrough_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr),
+ DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index f9795eb..4bba559 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -197,6 +197,8 @@ struct XenPCIPassthroughState {
PCIHostDeviceAddress hostaddr;
bool is_virtfn;
+ bool permissive;
+ bool permissive_warned;
XenHostPCIDevice real_device;
XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */
QLIST_HEAD(, XenPTRegGroup) reg_grps;
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 19f926b..f3cf069 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -101,6 +101,10 @@ static uint32_t get_throughable_mask(const XenPCIPassthroughState *s,
{
uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
+ if (!s->permissive) {
+ throughable_mask &= ~reg->res_mask;
+ }
+
return throughable_mask & valid_mask;
}
--
1.7.10.4
next prev parent reply other threads:[~2015-06-02 15:49 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-02 15:39 [Qemu-devel] [PULL 0/11] Xen PCI Passthrough security fixes Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 01/11] xen: properly gate host writes of modified PCI CFG contents Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 02/11] xen: don't allow guest to control MSI mask register Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 03/11] xen/MSI-X: limit error messages Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 04/11] xen/MSI: don't open-code pass-through of enable bit modifications Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 05/11] xen/pt: consolidate PM capability emu_mask Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 06/11] xen/pt: correctly handle PM status bit Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 07/11] xen/pt: split out calculation of throughable mask in PCI config space handling Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 08/11] xen/pt: mark all PCIe capability bits read-only Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 09/11] xen/pt: mark reserved bits in PCI config space fields Stefano Stabellini
2015-06-02 15:40 ` [Qemu-devel] [PULL 10/11] xen/pt: add a few PCI config space field descriptions Stefano Stabellini
2015-06-02 15:40 ` Stefano Stabellini [this message]
2015-06-02 16:43 ` [Qemu-devel] [PULL 0/11] Xen PCI Passthrough security fixes Peter Maydell
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=1433259628-4611-11-git-send-email-stefano.stabellini@eu.citrix.com \
--to=stefano.stabellini@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=xen-devel@lists.xensource.com \
/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;
as well as URLs for NNTP newsgroup(s).