summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch')
-rw-r--r--meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch137
1 files changed, 0 insertions, 137 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch
deleted file mode 100644
index 5bfcf5e166..0000000000
--- a/meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch
+++ /dev/null
@@ -1,137 +0,0 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From c25bbf1545a53ac051f9e51d4140e397660c10ae Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:01 +0000
8Subject: xen/pt: unknown PCI config space fields should be read-only
9Bug-Debian: http://bugs.debian.org/787547
10
11... by default. Add a per-device "permissive" mode similar to pciback's
12to allow restoring previous behavior (and hence break security again,
13i.e. should be used only for trusted guests).
14
15This is part of XSA-131.
16
17Signed-off-by: Jan Beulich <jbeulich@suse.com>
18Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
19Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>)
20---
21 hw/xen/xen_pt.c | 32 +++++++++++++++++++++++++++++---
22 hw/xen/xen_pt.h | 2 ++
23 hw/xen/xen_pt_config_init.c | 4 ++++
24 3 files changed, 35 insertions(+), 3 deletions(-)
25
26diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
27index 8923582..9afcda8 100644
28--- a/hw/xen/xen_pt.c
29+++ b/hw/xen/xen_pt.c
30@@ -239,6 +239,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
31 XenPTReg *reg_entry = NULL;
32 uint32_t find_addr = addr;
33 XenPTRegInfo *reg = NULL;
34+ bool wp_flag = false;
35
36 if (xen_pt_pci_config_access_check(d, addr, len)) {
37 return;
38@@ -278,6 +279,10 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
39
40 /* pass directly to the real device for passthrough type register group */
41 if (reg_grp_entry == NULL) {
42+ if (!s->permissive) {
43+ wb_mask = 0;
44+ wp_flag = true;
45+ }
46 goto out;
47 }
48
49@@ -298,12 +303,15 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
50 uint32_t real_offset = reg_grp_entry->base_offset + reg->offset;
51 uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3);
52 uint8_t *ptr_val = NULL;
53+ uint32_t wp_mask = reg->emu_mask | reg->ro_mask;
54
55 valid_mask <<= (find_addr - real_offset) << 3;
56 ptr_val = (uint8_t *)&val + (real_offset & 3);
57- if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
58- wb_mask &= ~((reg->emu_mask
59- >> ((find_addr - real_offset) << 3))
60+ if (!s->permissive) {
61+ wp_mask |= reg->res_mask;
62+ }
63+ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
64+ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3))
65 << ((len - emul_len) << 3));
66 }
67
68@@ -347,6 +355,16 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
69 } else {
70 /* nothing to do with passthrough type register,
71 * continue to find next byte */
72+ if (!s->permissive) {
73+ wb_mask &= ~(0xff << ((len - emul_len) << 3));
74+ /* Unused BARs will make it here, but we don't want to issue
75+ * warnings for writes to them (bogus writes get dealt with
76+ * above).
77+ */
78+ if (index < 0) {
79+ wp_flag = true;
80+ }
81+ }
82 emul_len--;
83 find_addr++;
84 }
85@@ -358,6 +376,13 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
86 memory_region_transaction_commit();
87
88 out:
89+ if (wp_flag && !s->permissive_warned) {
90+ s->permissive_warned = true;
91+ xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n",
92+ addr, len * 2, wb_mask);
93+ xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n");
94+ xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n");
95+ }
96 for (index = 0; wb_mask; index += len) {
97 /* unknown regs are passed through */
98 while (!(wb_mask & 0xff)) {
99@@ -824,6 +849,7 @@ static void xen_pt_unregister_device(PCIDevice *d)
100
101 static Property xen_pci_passthrough_properties[] = {
102 DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr),
103+ DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false),
104 DEFINE_PROP_END_OF_LIST(),
105 };
106
107diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
108index f9795eb..4bba559 100644
109--- a/hw/xen/xen_pt.h
110+++ b/hw/xen/xen_pt.h
111@@ -197,6 +197,8 @@ struct XenPCIPassthroughState {
112
113 PCIHostDeviceAddress hostaddr;
114 bool is_virtfn;
115+ bool permissive;
116+ bool permissive_warned;
117 XenHostPCIDevice real_device;
118 XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */
119 QLIST_HEAD(, XenPTRegGroup) reg_grps;
120diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
121index 19f926b..f3cf069 100644
122--- a/hw/xen/xen_pt_config_init.c
123+++ b/hw/xen/xen_pt_config_init.c
124@@ -101,6 +101,10 @@ static uint32_t get_throughable_mask(const XenPCIPassthroughState *s,
125 {
126 uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
127
128+ if (!s->permissive) {
129+ throughable_mask &= ~reg->res_mask;
130+ }
131+
132 return throughable_mask & valid_mask;
133 }
134
135--
1362.1.4
137