summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/qemu
diff options
context:
space:
mode:
authorKai Kang <kai.kang@windriver.com>2015-06-18 17:02:42 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-06-27 22:42:51 +0100
commita1bac0f7dfe3e1a29c03f7e307ea6da355859409 (patch)
tree03883a126f0c7c35d12eb6e01a4f48184ad3d7f2 /meta/recipes-devtools/qemu
parenta8ae7317e2da254f65d05497b5eaae9d57c5c1e9 (diff)
downloadpoky-a1bac0f7dfe3e1a29c03f7e307ea6da355859409.tar.gz
qemu: backport patches to fix CVE issues
Backport patches to fix CVE-2015-4103, CVE-2015-4104, CVE-2015-4105 and CVE-2015-4106. These patches are from debian, but they are originally from: http://git.qemu.org/?p=qemu.git;a=shortlog;h=c25bbf1 (From OE-Core rev: 496b3ffba6755bb76709c88cf81399c9d23f830a) Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/qemu')
-rw-r--r--meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch140
-rw-r--r--meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch194
-rw-r--r--meta/recipes-devtools/qemu/qemu/03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch90
-rw-r--r--meta/recipes-devtools/qemu/qemu/04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch76
-rw-r--r--meta/recipes-devtools/qemu/qemu/05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch86
-rw-r--r--meta/recipes-devtools/qemu/qemu/06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch38
-rw-r--r--meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch265
-rw-r--r--meta/recipes-devtools/qemu/qemu/08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch38
-rw-r--r--meta/recipes-devtools/qemu/qemu/09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch94
-rw-r--r--meta/recipes-devtools/qemu/qemu/10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch77
-rw-r--r--meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch137
-rw-r--r--meta/recipes-devtools/qemu/qemu_2.3.0.bb13
12 files changed, 1247 insertions, 1 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch b/meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch
new file mode 100644
index 0000000000..42a496042a
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch
@@ -0,0 +1,140 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 5c83b2f5b4b956e91dd6e5711f14df7ab800aefb Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:00 +0000
8Subject: xen: properly gate host writes of modified PCI CFG contents
9Bug-Debian: http://bugs.debian.org/787547
10
11The old logic didn't work as intended when an access spanned multiple
12fields (for example a 32-bit access to the location of the MSI Message
13Data field with the high 16 bits not being covered by any known field).
14Remove it and derive which fields not to write to from the accessed
15fields' emulation masks: When they're all ones, there's no point in
16doing any host write.
17
18This fixes a secondary issue at once: We obviously shouldn't make any
19host write attempt when already the host read failed.
20
21This is XSA-128.
22
23Signed-off-by: Jan Beulich <jbeulich@suse.com>
24Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
25---
26 hw/xen/xen_pt.c | 25 +++++++++++++++++++++----
27 hw/xen/xen_pt.h | 2 --
28 hw/xen/xen_pt_config_init.c | 4 ----
29 3 files changed, 21 insertions(+), 10 deletions(-)
30
31diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
32index d095c08..8923582 100644
33--- a/hw/xen/xen_pt.c
34+++ b/hw/xen/xen_pt.c
35@@ -234,7 +234,7 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
36 int index = 0;
37 XenPTRegGroup *reg_grp_entry = NULL;
38 int rc = 0;
39- uint32_t read_val = 0;
40+ uint32_t read_val = 0, wb_mask;
41 int emul_len = 0;
42 XenPTReg *reg_entry = NULL;
43 uint32_t find_addr = addr;
44@@ -271,6 +271,9 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
45 if (rc < 0) {
46 XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc);
47 memset(&read_val, 0xff, len);
48+ wb_mask = 0;
49+ } else {
50+ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3);
51 }
52
53 /* pass directly to the real device for passthrough type register group */
54@@ -298,6 +301,11 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
55
56 valid_mask <<= (find_addr - real_offset) << 3;
57 ptr_val = (uint8_t *)&val + (real_offset & 3);
58+ if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) {
59+ wb_mask &= ~((reg->emu_mask
60+ >> ((find_addr - real_offset) << 3))
61+ << ((len - emul_len) << 3));
62+ }
63
64 /* do emulation based on register size */
65 switch (reg->size) {
66@@ -350,10 +358,19 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr,
67 memory_region_transaction_commit();
68
69 out:
70- if (!(reg && reg->no_wb)) {
71+ for (index = 0; wb_mask; index += len) {
72 /* unknown regs are passed through */
73- rc = xen_host_pci_set_block(&s->real_device, addr,
74- (uint8_t *)&val, len);
75+ while (!(wb_mask & 0xff)) {
76+ index++;
77+ wb_mask >>= 8;
78+ }
79+ len = 0;
80+ do {
81+ len++;
82+ wb_mask >>= 8;
83+ } while (wb_mask & 0xff);
84+ rc = xen_host_pci_set_block(&s->real_device, addr + index,
85+ (uint8_t *)&val + index, len);
86
87 if (rc < 0) {
88 XEN_PT_ERR(d, "pci_write_block failed. return value: %d.\n", rc);
89diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
90index 942dc60..52ceb85 100644
91--- a/hw/xen/xen_pt.h
92+++ b/hw/xen/xen_pt.h
93@@ -105,8 +105,6 @@ struct XenPTRegInfo {
94 uint32_t ro_mask;
95 /* reg emulate field mask (ON:emu, OFF:passthrough) */
96 uint32_t emu_mask;
97- /* no write back allowed */
98- uint32_t no_wb;
99 xen_pt_conf_reg_init init;
100 /* read/write function pointer
101 * for double_word/word/byte size */
102diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
103index 95a51db..dae0519 100644
104--- a/hw/xen/xen_pt_config_init.c
105+++ b/hw/xen/xen_pt_config_init.c
106@@ -1279,7 +1279,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
107 .init_val = 0x00000000,
108 .ro_mask = 0x00000003,
109 .emu_mask = 0xFFFFFFFF,
110- .no_wb = 1,
111 .init = xen_pt_common_reg_init,
112 .u.dw.read = xen_pt_long_reg_read,
113 .u.dw.write = xen_pt_msgaddr32_reg_write,
114@@ -1291,7 +1290,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
115 .init_val = 0x00000000,
116 .ro_mask = 0x00000000,
117 .emu_mask = 0xFFFFFFFF,
118- .no_wb = 1,
119 .init = xen_pt_msgaddr64_reg_init,
120 .u.dw.read = xen_pt_long_reg_read,
121 .u.dw.write = xen_pt_msgaddr64_reg_write,
122@@ -1303,7 +1301,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
123 .init_val = 0x0000,
124 .ro_mask = 0x0000,
125 .emu_mask = 0xFFFF,
126- .no_wb = 1,
127 .init = xen_pt_msgdata_reg_init,
128 .u.w.read = xen_pt_word_reg_read,
129 .u.w.write = xen_pt_msgdata_reg_write,
130@@ -1315,7 +1312,6 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
131 .init_val = 0x0000,
132 .ro_mask = 0x0000,
133 .emu_mask = 0xFFFF,
134- .no_wb = 1,
135 .init = xen_pt_msgdata_reg_init,
136 .u.w.read = xen_pt_word_reg_read,
137 .u.w.write = xen_pt_msgdata_reg_write,
138--
1392.1.4
140
diff --git a/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch b/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch
new file mode 100644
index 0000000000..252bf0223c
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch
@@ -0,0 +1,194 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 7611dae8a69f0f1775ba1a9a942961c2aa10d88e Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:00 +0000
8Subject: xen: don't allow guest to control MSI mask register
9Bug-Debian: http://bugs.debian.org/787547
10
11It's being used by the hypervisor. For now simply mimic a device not
12capable of masking, and fully emulate any accesses a guest may issue
13nevertheless as simple reads/writes without side effects.
14
15This is XSA-129.
16
17Signed-off-by: Jan Beulich <jbeulich@suse.com>
18Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
19---
20 hw/pci/msi.c | 4 --
21 hw/xen/xen_pt_config_init.c | 98 ++++++++++++++++++++++++++++++++++++++++-----
22 include/hw/pci/pci_regs.h | 2 +
23 3 files changed, 90 insertions(+), 14 deletions(-)
24
25diff --git a/hw/pci/msi.c b/hw/pci/msi.c
26index c111dba..f9c0484 100644
27--- a/hw/pci/msi.c
28+++ b/hw/pci/msi.c
29@@ -21,10 +21,6 @@
30 #include "hw/pci/msi.h"
31 #include "qemu/range.h"
32
33-/* Eventually those constants should go to Linux pci_regs.h */
34-#define PCI_MSI_PENDING_32 0x10
35-#define PCI_MSI_PENDING_64 0x14
36-
37 /* PCI_MSI_ADDRESS_LO */
38 #define PCI_MSI_ADDRESS_LO_MASK (~0x3)
39
40diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
41index dae0519..68b8f22 100644
42--- a/hw/xen/xen_pt_config_init.c
43+++ b/hw/xen/xen_pt_config_init.c
44@@ -1016,13 +1016,9 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
45 */
46
47 /* Helper */
48-static bool xen_pt_msgdata_check_type(uint32_t offset, uint16_t flags)
49-{
50- /* check the offset whether matches the type or not */
51- bool is_32 = (offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT);
52- bool is_64 = (offset == PCI_MSI_DATA_64) && (flags & PCI_MSI_FLAGS_64BIT);
53- return is_32 || is_64;
54-}
55+#define xen_pt_msi_check_type(offset, flags, what) \
56+ ((offset) == ((flags) & PCI_MSI_FLAGS_64BIT ? \
57+ PCI_MSI_##what##_64 : PCI_MSI_##what##_32))
58
59 /* Message Control register */
60 static int xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s,
61@@ -1134,7 +1130,45 @@ static int xen_pt_msgdata_reg_init(XenPCIPassthroughState *s,
62 uint32_t offset = reg->offset;
63
64 /* check the offset whether matches the type or not */
65- if (xen_pt_msgdata_check_type(offset, flags)) {
66+ if (xen_pt_msi_check_type(offset, flags, DATA)) {
67+ *data = reg->init_val;
68+ } else {
69+ *data = XEN_PT_INVALID_REG;
70+ }
71+ return 0;
72+}
73+
74+/* this function will be called twice (for 32 bit and 64 bit type) */
75+/* initialize Mask register */
76+static int xen_pt_mask_reg_init(XenPCIPassthroughState *s,
77+ XenPTRegInfo *reg, uint32_t real_offset,
78+ uint32_t *data)
79+{
80+ uint32_t flags = s->msi->flags;
81+
82+ /* check the offset whether matches the type or not */
83+ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
84+ *data = XEN_PT_INVALID_REG;
85+ } else if (xen_pt_msi_check_type(reg->offset, flags, MASK)) {
86+ *data = reg->init_val;
87+ } else {
88+ *data = XEN_PT_INVALID_REG;
89+ }
90+ return 0;
91+}
92+
93+/* this function will be called twice (for 32 bit and 64 bit type) */
94+/* initialize Pending register */
95+static int xen_pt_pending_reg_init(XenPCIPassthroughState *s,
96+ XenPTRegInfo *reg, uint32_t real_offset,
97+ uint32_t *data)
98+{
99+ uint32_t flags = s->msi->flags;
100+
101+ /* check the offset whether matches the type or not */
102+ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) {
103+ *data = XEN_PT_INVALID_REG;
104+ } else if (xen_pt_msi_check_type(reg->offset, flags, PENDING)) {
105 *data = reg->init_val;
106 } else {
107 *data = XEN_PT_INVALID_REG;
108@@ -1222,7 +1256,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
109 uint32_t offset = reg->offset;
110
111 /* check the offset whether matches the type or not */
112- if (!xen_pt_msgdata_check_type(offset, msi->flags)) {
113+ if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) {
114 /* exit I/O emulator */
115 XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n");
116 return -1;
117@@ -1267,7 +1301,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
118 .size = 2,
119 .init_val = 0x0000,
120 .ro_mask = 0xFF8E,
121- .emu_mask = 0x007F,
122+ .emu_mask = 0x017F,
123 .init = xen_pt_msgctrl_reg_init,
124 .u.w.read = xen_pt_word_reg_read,
125 .u.w.write = xen_pt_msgctrl_reg_write,
126@@ -1316,6 +1350,50 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
127 .u.w.read = xen_pt_word_reg_read,
128 .u.w.write = xen_pt_msgdata_reg_write,
129 },
130+ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
131+ {
132+ .offset = PCI_MSI_MASK_32,
133+ .size = 4,
134+ .init_val = 0x00000000,
135+ .ro_mask = 0xFFFFFFFF,
136+ .emu_mask = 0xFFFFFFFF,
137+ .init = xen_pt_mask_reg_init,
138+ .u.dw.read = xen_pt_long_reg_read,
139+ .u.dw.write = xen_pt_long_reg_write,
140+ },
141+ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
142+ {
143+ .offset = PCI_MSI_MASK_64,
144+ .size = 4,
145+ .init_val = 0x00000000,
146+ .ro_mask = 0xFFFFFFFF,
147+ .emu_mask = 0xFFFFFFFF,
148+ .init = xen_pt_mask_reg_init,
149+ .u.dw.read = xen_pt_long_reg_read,
150+ .u.dw.write = xen_pt_long_reg_write,
151+ },
152+ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
153+ {
154+ .offset = PCI_MSI_MASK_32 + 4,
155+ .size = 4,
156+ .init_val = 0x00000000,
157+ .ro_mask = 0xFFFFFFFF,
158+ .emu_mask = 0x00000000,
159+ .init = xen_pt_pending_reg_init,
160+ .u.dw.read = xen_pt_long_reg_read,
161+ .u.dw.write = xen_pt_long_reg_write,
162+ },
163+ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
164+ {
165+ .offset = PCI_MSI_MASK_64 + 4,
166+ .size = 4,
167+ .init_val = 0x00000000,
168+ .ro_mask = 0xFFFFFFFF,
169+ .emu_mask = 0x00000000,
170+ .init = xen_pt_pending_reg_init,
171+ .u.dw.read = xen_pt_long_reg_read,
172+ .u.dw.write = xen_pt_long_reg_write,
173+ },
174 {
175 .size = 0,
176 },
177diff --git a/include/hw/pci/pci_regs.h b/include/hw/pci/pci_regs.h
178index 56a404b..57e8c80 100644
179--- a/include/hw/pci/pci_regs.h
180+++ b/include/hw/pci/pci_regs.h
181@@ -298,8 +298,10 @@
182 #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
183 #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
184 #define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */
185+#define PCI_MSI_PENDING_32 16 /* Pending bits register for 32-bit devices */
186 #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
187 #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */
188+#define PCI_MSI_PENDING_64 20 /* Pending bits register for 32-bit devices */
189
190 /* MSI-X registers */
191 #define PCI_MSIX_FLAGS 2
192--
1932.1.4
194
diff --git a/meta/recipes-devtools/qemu/qemu/03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch b/meta/recipes-devtools/qemu/qemu/03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch
new file mode 100644
index 0000000000..8bb2230333
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch
@@ -0,0 +1,90 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From b38ec5ee7a581776bbce0bdaecb397632c3c4791 Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:00 +0000
8Subject: xen/MSI-X: limit error messages
9Bug-Debian: http://bugs.debian.org/787547
10
11Limit error messages resulting from bad guest behavior to avoid allowing
12the guest to cause the control domain's disk to fill.
13
14The first message in pci_msix_write() can simply be deleted, as this
15is indeed bad guest behavior, but such out of bounds writes don't
16really need to be logged.
17
18The second one is more problematic, as there guest behavior may only
19appear to be wrong: For one, the old logic didn't take the mask-all bit
20into account. And then this shouldn't depend on host device state (i.e.
21the host may have masked the entry without the guest having done so).
22Plus these writes shouldn't be dropped even when an entry is unmasked.
23Instead, if they can't be made take effect right away, they should take
24effect on the next unmasking or enabling operation - the specification
25explicitly describes such caching behavior. Until we can validly drop
26the message (implementing such caching/latching behavior), issue the
27message just once per MSI-X table entry.
28
29Note that the log message in pci_msix_read() similar to the one being
30removed here is not an issue: "addr" being of unsigned type, and the
31maximum size of the MSI-X table being 32k, entry_nr simply can't be
32negative and hence the conditonal guarding issuing of the message will
33never be true.
34
35This is XSA-130.
36
37Signed-off-by: Jan Beulich <jbeulich@suse.com>
38Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
39---
40 hw/xen/xen_pt.h | 1 +
41 hw/xen/xen_pt_msi.c | 12 +++++++-----
42 2 files changed, 8 insertions(+), 5 deletions(-)
43
44diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
45index 52ceb85..8c9b6c2 100644
46--- a/hw/xen/xen_pt.h
47+++ b/hw/xen/xen_pt.h
48@@ -175,6 +175,7 @@ typedef struct XenPTMSIXEntry {
49 uint32_t data;
50 uint32_t vector_ctrl;
51 bool updated; /* indicate whether MSI ADDR or DATA is updated */
52+ bool warned; /* avoid issuing (bogus) warning more than once */
53 } XenPTMSIXEntry;
54 typedef struct XenPTMSIX {
55 uint32_t ctrl_offset;
56diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
57index 9ed9321..68db623 100644
58--- a/hw/xen/xen_pt_msi.c
59+++ b/hw/xen/xen_pt_msi.c
60@@ -434,11 +434,10 @@ static void pci_msix_write(void *opaque, hwaddr addr,
61 XenPCIPassthroughState *s = opaque;
62 XenPTMSIX *msix = s->msix;
63 XenPTMSIXEntry *entry;
64- int entry_nr, offset;
65+ unsigned int entry_nr, offset;
66
67 entry_nr = addr / PCI_MSIX_ENTRY_SIZE;
68- if (entry_nr < 0 || entry_nr >= msix->total_entries) {
69- XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr);
70+ if (entry_nr >= msix->total_entries) {
71 return;
72 }
73 entry = &msix->msix_entry[entry_nr];
74@@ -460,8 +459,11 @@ static void pci_msix_write(void *opaque, hwaddr addr,
75 + PCI_MSIX_ENTRY_VECTOR_CTRL;
76
77 if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
78- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is"
79- " already enabled.\n", entry_nr);
80+ if (!entry->warned) {
81+ entry->warned = true;
82+ XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is"
83+ " already enabled.\n", entry_nr);
84+ }
85 return;
86 }
87
88--
892.1.4
90
diff --git a/meta/recipes-devtools/qemu/qemu/04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch
new file mode 100644
index 0000000000..87fb7f6fb7
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch
@@ -0,0 +1,76 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From d1d35cf4ffb6a60a356193397919e83306d0bb74 Mon Sep 17 00:00:00 2001
6From: Jan Beulich <jbeulich@suse.com>
7Date: Tue, 2 Jun 2015 15:07:01 +0000
8Subject: xen/MSI: don't open-code pass-through of enable bit modifications
9Bug-Debian: http://bugs.debian.org/787547
10
11Without this the actual XSA-131 fix would cause the enable bit to not
12get set anymore (due to the write back getting suppressed there based
13on the OR of emu_mask, ro_mask, and res_mask).
14
15Note that the fiddling with the enable bit shouldn't really be done by
16qemu, but making this work right (via libxc and the hypervisor) will
17require more extensive changes, which can be postponed until after the
18security issue got addressed.
19
20This is a preparatory patch for XSA-131.
21
22Signed-off-by: Jan Beulich <jbeulich@suse.com>
23Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
24---
25 hw/xen/xen_pt_config_init.c | 10 ++--------
26 1 file changed, 2 insertions(+), 8 deletions(-)
27
28diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
29index 68b8f22..436d0fd 100644
30--- a/hw/xen/xen_pt_config_init.c
31+++ b/hw/xen/xen_pt_config_init.c
32@@ -1053,7 +1053,6 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
33 XenPTMSI *msi = s->msi;
34 uint16_t writable_mask = 0;
35 uint16_t throughable_mask = 0;
36- uint16_t raw_val;
37
38 /* Currently no support for multi-vector */
39 if (*val & PCI_MSI_FLAGS_QSIZE) {
40@@ -1066,12 +1065,11 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
41 msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE;
42
43 /* create value for writing to I/O device register */
44- raw_val = *val;
45 throughable_mask = ~reg->emu_mask & valid_mask;
46 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
47
48 /* update MSI */
49- if (raw_val & PCI_MSI_FLAGS_ENABLE) {
50+ if (*val & PCI_MSI_FLAGS_ENABLE) {
51 /* setup MSI pirq for the first time */
52 if (!msi->initialized) {
53 /* Init physical one */
54@@ -1099,10 +1097,6 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
55 xen_pt_msi_disable(s);
56 }
57
58- /* pass through MSI_ENABLE bit */
59- *val &= ~PCI_MSI_FLAGS_ENABLE;
60- *val |= raw_val & PCI_MSI_FLAGS_ENABLE;
61-
62 return 0;
63 }
64
65@@ -1301,7 +1295,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
66 .size = 2,
67 .init_val = 0x0000,
68 .ro_mask = 0xFF8E,
69- .emu_mask = 0x017F,
70+ .emu_mask = 0x017E,
71 .init = xen_pt_msgctrl_reg_init,
72 .u.w.read = xen_pt_word_reg_read,
73 .u.w.write = xen_pt_msgctrl_reg_write,
74--
752.1.4
76
diff --git a/meta/recipes-devtools/qemu/qemu/05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch
new file mode 100644
index 0000000000..e9e4fccb4d
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch
@@ -0,0 +1,86 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From d61bb2482dc0c7426f451f23ba7e2748ae2cc06d 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: consolidate PM capability emu_mask
9Bug-Debian: http://bugs.debian.org/787547
10
11There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing
12PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local
13emu_mask variable - we can have the same effect by setting the field
14descriptor's emu_mask member suitably right away. Note that
15xen_pt_pmcsr_reg_write() is being retained in order to allow later
16patches to be less intrusive.
17
18This is a preparatory patch for XSA-131.
19
20Signed-off-by: Jan Beulich <jbeulich@suse.com>
21Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
22Acked-by: Ian Campbell <ian.campbell@citrix.com>
23---
24 hw/xen/xen_pt_config_init.c | 25 ++++---------------------
25 1 file changed, 4 insertions(+), 21 deletions(-)
26
27diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
28index 436d0fd..516236a 100644
29--- a/hw/xen/xen_pt_config_init.c
30+++ b/hw/xen/xen_pt_config_init.c
31@@ -933,38 +933,21 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
32 * Power Management Capability
33 */
34
35-/* read Power Management Control/Status register */
36-static int xen_pt_pmcsr_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
37- uint16_t *value, uint16_t valid_mask)
38-{
39- XenPTRegInfo *reg = cfg_entry->reg;
40- uint16_t valid_emu_mask = reg->emu_mask;
41-
42- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
43-
44- valid_emu_mask = valid_emu_mask & valid_mask;
45- *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
46-
47- return 0;
48-}
49 /* write Power Management Control/Status register */
50 static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
51 XenPTReg *cfg_entry, uint16_t *val,
52 uint16_t dev_value, uint16_t valid_mask)
53 {
54 XenPTRegInfo *reg = cfg_entry->reg;
55- uint16_t emu_mask = reg->emu_mask;
56 uint16_t writable_mask = 0;
57 uint16_t throughable_mask = 0;
58
59- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
60-
61 /* modify emulate register */
62- writable_mask = emu_mask & ~reg->ro_mask & valid_mask;
63+ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
64 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
65
66 /* create value for writing to I/O device register */
67- throughable_mask = ~emu_mask & valid_mask;
68+ throughable_mask = ~reg->emu_mask & valid_mask;
69 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
70
71 return 0;
72@@ -1000,9 +983,9 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
73 .size = 2,
74 .init_val = 0x0008,
75 .ro_mask = 0xE1FC,
76- .emu_mask = 0x8100,
77+ .emu_mask = 0x810B,
78 .init = xen_pt_common_reg_init,
79- .u.w.read = xen_pt_pmcsr_reg_read,
80+ .u.w.read = xen_pt_word_reg_read,
81 .u.w.write = xen_pt_pmcsr_reg_write,
82 },
83 {
84--
852.1.4
86
diff --git a/meta/recipes-devtools/qemu/qemu/06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch
new file mode 100644
index 0000000000..37758cdd58
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch
@@ -0,0 +1,38 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From c4ff1e68c621928abc680266cad0a451686c403b 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: correctly handle PM status bit
9Bug-Debian: http://bugs.debian.org/787547
10
11xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C
12nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS).
13
14This is a preparatory patch for XSA-131.
15
16Signed-off-by: Jan Beulich <jbeulich@suse.com>
17Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
18---
19 hw/xen/xen_pt_config_init.c | 3 ++-
20 1 file changed, 2 insertions(+), 1 deletion(-)
21
22diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
23index 516236a..027ac32 100644
24--- a/hw/xen/xen_pt_config_init.c
25+++ b/hw/xen/xen_pt_config_init.c
26@@ -948,7 +948,8 @@ static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
27
28 /* create value for writing to I/O device register */
29 throughable_mask = ~reg->emu_mask & valid_mask;
30- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
31+ *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS,
32+ throughable_mask);
33
34 return 0;
35 }
36--
372.1.4
38
diff --git a/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
new file mode 100644
index 0000000000..28b75922d7
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
@@ -0,0 +1,265 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 0e7ef22136955169a0fd03c4e41af95662352733 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: split out calculation of throughable mask in
9 PCI config space handling
10Bug-Debian: http://bugs.debian.org/787547
11
12This is just to avoid having to adjust that calculation later in
13multiple places.
14
15Note that including ->ro_mask in get_throughable_mask()'s calculation
16is only an apparent (i.e. benign) behavioral change: For r/o fields it
17doesn't matter > whether they get passed through - either the same flag
18is also set in emu_mask (then there's no change at all) or the field is
19r/o in hardware (and hence a write won't change it anyway).
20
21This is a preparatory patch for XSA-131.
22
23Signed-off-by: Jan Beulich <jbeulich@suse.com>
24Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
25Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
26---
27 hw/xen/xen_pt_config_init.c | 51 ++++++++++++++++++---------------------------
28 1 file changed, 20 insertions(+), 31 deletions(-)
29
30diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
31index 027ac32..3833b9e 100644
32--- a/hw/xen/xen_pt_config_init.c
33+++ b/hw/xen/xen_pt_config_init.c
34@@ -95,6 +95,14 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t address)
35 return NULL;
36 }
37
38+static uint32_t get_throughable_mask(const XenPCIPassthroughState *s,
39+ const XenPTRegInfo *reg,
40+ uint32_t valid_mask)
41+{
42+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
43+
44+ return throughable_mask & valid_mask;
45+}
46
47 /****************
48 * general register functions
49@@ -157,14 +165,13 @@ static int xen_pt_byte_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
50 {
51 XenPTRegInfo *reg = cfg_entry->reg;
52 uint8_t writable_mask = 0;
53- uint8_t throughable_mask = 0;
54+ uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
55
56 /* modify emulate register */
57 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
58 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
59
60 /* create value for writing to I/O device register */
61- throughable_mask = ~reg->emu_mask & valid_mask;
62 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
63
64 return 0;
65@@ -175,14 +182,13 @@ static int xen_pt_word_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
66 {
67 XenPTRegInfo *reg = cfg_entry->reg;
68 uint16_t writable_mask = 0;
69- uint16_t throughable_mask = 0;
70+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
71
72 /* modify emulate register */
73 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
74 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
75
76 /* create value for writing to I/O device register */
77- throughable_mask = ~reg->emu_mask & valid_mask;
78 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
79
80 return 0;
81@@ -193,14 +199,13 @@ static int xen_pt_long_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
82 {
83 XenPTRegInfo *reg = cfg_entry->reg;
84 uint32_t writable_mask = 0;
85- uint32_t throughable_mask = 0;
86+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
87
88 /* modify emulate register */
89 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
90 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
91
92 /* create value for writing to I/O device register */
93- throughable_mask = ~reg->emu_mask & valid_mask;
94 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
95
96 return 0;
97@@ -292,15 +297,13 @@ static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
98 {
99 XenPTRegInfo *reg = cfg_entry->reg;
100 uint16_t writable_mask = 0;
101- uint16_t throughable_mask = 0;
102+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
103
104 /* modify emulate register */
105 writable_mask = ~reg->ro_mask & valid_mask;
106 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
107
108 /* create value for writing to I/O device register */
109- throughable_mask = ~reg->emu_mask & valid_mask;
110-
111 if (*val & PCI_COMMAND_INTX_DISABLE) {
112 throughable_mask |= PCI_COMMAND_INTX_DISABLE;
113 } else {
114@@ -454,7 +457,6 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
115 PCIDevice *d = &s->dev;
116 const PCIIORegion *r;
117 uint32_t writable_mask = 0;
118- uint32_t throughable_mask = 0;
119 uint32_t bar_emu_mask = 0;
120 uint32_t bar_ro_mask = 0;
121 uint32_t r_size = 0;
122@@ -511,8 +513,7 @@ static int xen_pt_bar_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
123 }
124
125 /* create value for writing to I/O device register */
126- throughable_mask = ~bar_emu_mask & valid_mask;
127- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
128+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
129
130 return 0;
131 }
132@@ -526,9 +527,8 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
133 XenPTRegion *base = NULL;
134 PCIDevice *d = (PCIDevice *)&s->dev;
135 uint32_t writable_mask = 0;
136- uint32_t throughable_mask = 0;
137+ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
138 pcibus_t r_size = 0;
139- uint32_t bar_emu_mask = 0;
140 uint32_t bar_ro_mask = 0;
141
142 r_size = d->io_regions[PCI_ROM_SLOT].size;
143@@ -537,7 +537,6 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
144 r_size = xen_pt_get_emul_size(base->bar_flag, r_size);
145
146 /* set emulate mask and read-only mask */
147- bar_emu_mask = reg->emu_mask;
148 bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE;
149
150 /* modify emulate register */
151@@ -545,7 +544,6 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
152 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
153
154 /* create value for writing to I/O device register */
155- throughable_mask = ~bar_emu_mask & valid_mask;
156 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
157
158 return 0;
159@@ -940,14 +938,13 @@ static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
160 {
161 XenPTRegInfo *reg = cfg_entry->reg;
162 uint16_t writable_mask = 0;
163- uint16_t throughable_mask = 0;
164+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
165
166 /* modify emulate register */
167 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
168 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
169
170 /* create value for writing to I/O device register */
171- throughable_mask = ~reg->emu_mask & valid_mask;
172 *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS,
173 throughable_mask);
174
175@@ -1036,7 +1033,7 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
176 XenPTRegInfo *reg = cfg_entry->reg;
177 XenPTMSI *msi = s->msi;
178 uint16_t writable_mask = 0;
179- uint16_t throughable_mask = 0;
180+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
181
182 /* Currently no support for multi-vector */
183 if (*val & PCI_MSI_FLAGS_QSIZE) {
184@@ -1049,7 +1046,6 @@ static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,
185 msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE;
186
187 /* create value for writing to I/O device register */
188- throughable_mask = ~reg->emu_mask & valid_mask;
189 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
190
191 /* update MSI */
192@@ -1161,7 +1157,6 @@ static int xen_pt_msgaddr32_reg_write(XenPCIPassthroughState *s,
193 {
194 XenPTRegInfo *reg = cfg_entry->reg;
195 uint32_t writable_mask = 0;
196- uint32_t throughable_mask = 0;
197 uint32_t old_addr = cfg_entry->data;
198
199 /* modify emulate register */
200@@ -1170,8 +1165,7 @@ static int xen_pt_msgaddr32_reg_write(XenPCIPassthroughState *s,
201 s->msi->addr_lo = cfg_entry->data;
202
203 /* create value for writing to I/O device register */
204- throughable_mask = ~reg->emu_mask & valid_mask;
205- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
206+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
207
208 /* update MSI */
209 if (cfg_entry->data != old_addr) {
210@@ -1189,7 +1183,6 @@ static int xen_pt_msgaddr64_reg_write(XenPCIPassthroughState *s,
211 {
212 XenPTRegInfo *reg = cfg_entry->reg;
213 uint32_t writable_mask = 0;
214- uint32_t throughable_mask = 0;
215 uint32_t old_addr = cfg_entry->data;
216
217 /* check whether the type is 64 bit or not */
218@@ -1206,8 +1199,7 @@ static int xen_pt_msgaddr64_reg_write(XenPCIPassthroughState *s,
219 s->msi->addr_hi = cfg_entry->data;
220
221 /* create value for writing to I/O device register */
222- throughable_mask = ~reg->emu_mask & valid_mask;
223- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
224+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
225
226 /* update MSI */
227 if (cfg_entry->data != old_addr) {
228@@ -1229,7 +1221,6 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
229 XenPTRegInfo *reg = cfg_entry->reg;
230 XenPTMSI *msi = s->msi;
231 uint16_t writable_mask = 0;
232- uint16_t throughable_mask = 0;
233 uint16_t old_data = cfg_entry->data;
234 uint32_t offset = reg->offset;
235
236@@ -1247,8 +1238,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
237 msi->data = cfg_entry->data;
238
239 /* create value for writing to I/O device register */
240- throughable_mask = ~reg->emu_mask & valid_mask;
241- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
242+ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);
243
244 /* update MSI */
245 if (cfg_entry->data != old_data) {
246@@ -1410,7 +1400,7 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
247 {
248 XenPTRegInfo *reg = cfg_entry->reg;
249 uint16_t writable_mask = 0;
250- uint16_t throughable_mask = 0;
251+ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);
252 int debug_msix_enabled_old;
253
254 /* modify emulate register */
255@@ -1418,7 +1408,6 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
256 cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);
257
258 /* create value for writing to I/O device register */
259- throughable_mask = ~reg->emu_mask & valid_mask;
260 *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);
261
262 /* update MSI-X */
263--
2642.1.4
265
diff --git a/meta/recipes-devtools/qemu/qemu/08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch
new file mode 100644
index 0000000000..4236a1295f
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch
@@ -0,0 +1,38 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 45ebe3916ab16f859ed930e92fbd52d84d5dcdaf 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: mark all PCIe capability bits read-only
9Bug-Debian: http://bugs.debian.org/787547
10
11xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read-
12only to avoid unintended write-back (just a precaution, the field ought
13to be read-only in hardware).
14
15This is a preparatory patch for XSA-131.
16
17Signed-off-by: Jan Beulich <jbeulich@suse.com>
18Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
19---
20 hw/xen/xen_pt_config_init.c | 2 +-
21 1 file changed, 1 insertion(+), 1 deletion(-)
22
23diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
24index 3833b9e..9f6c00e 100644
25--- a/hw/xen/xen_pt_config_init.c
26+++ b/hw/xen/xen_pt_config_init.c
27@@ -871,7 +871,7 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
28 .offset = PCI_EXP_DEVCAP,
29 .size = 4,
30 .init_val = 0x00000000,
31- .ro_mask = 0x1FFCFFFF,
32+ .ro_mask = 0xFFFFFFFF,
33 .emu_mask = 0x10000000,
34 .init = xen_pt_common_reg_init,
35 .u.dw.read = xen_pt_long_reg_read,
36--
372.1.4
38
diff --git a/meta/recipes-devtools/qemu/qemu/09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch
new file mode 100644
index 0000000000..99b8ba4904
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch
@@ -0,0 +1,94 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From 0ad3393ad032f76e88b4dbd04d36ad84dff75dd6 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: mark reserved bits in PCI config space fields
9Bug-Debian: http://bugs.debian.org/787547
10
11The adjustments are solely to make the subsequent patches work right
12(and hence make the patch set consistent), namely if permissive mode
13(introduced by the last patch) gets used (as both reserved registers
14and reserved fields must be similarly protected from guest access in
15default mode, but the guest should be allowed access to them in
16permissive mode).
17
18This is a preparatory patch for XSA-131.
19
20Signed-off-by: Jan Beulich <jbeulich@suse.com>
21---
22 hw/xen/xen_pt.h | 2 ++
23 hw/xen/xen_pt_config_init.c | 14 +++++++++-----
24 2 files changed, 11 insertions(+), 5 deletions(-)
25
26diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
27index 8c9b6c2..f9795eb 100644
28--- a/hw/xen/xen_pt.h
29+++ b/hw/xen/xen_pt.h
30@@ -101,6 +101,8 @@ struct XenPTRegInfo {
31 uint32_t offset;
32 uint32_t size;
33 uint32_t init_val;
34+ /* reg reserved field mask (ON:reserved, OFF:defined) */
35+ uint32_t res_mask;
36 /* reg read only field mask (ON:RO/ROS, OFF:other) */
37 uint32_t ro_mask;
38 /* reg emulate field mask (ON:emu, OFF:passthrough) */
39diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
40index 9f6c00e..efd8bac 100644
41--- a/hw/xen/xen_pt_config_init.c
42+++ b/hw/xen/xen_pt_config_init.c
43@@ -578,7 +578,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
44 .offset = PCI_COMMAND,
45 .size = 2,
46 .init_val = 0x0000,
47- .ro_mask = 0xF880,
48+ .res_mask = 0xF880,
49 .emu_mask = 0x0743,
50 .init = xen_pt_common_reg_init,
51 .u.w.read = xen_pt_word_reg_read,
52@@ -603,7 +603,8 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
53 .offset = PCI_STATUS,
54 .size = 2,
55 .init_val = 0x0000,
56- .ro_mask = 0x06FF,
57+ .res_mask = 0x0007,
58+ .ro_mask = 0x06F8,
59 .emu_mask = 0x0010,
60 .init = xen_pt_status_reg_init,
61 .u.w.read = xen_pt_word_reg_read,
62@@ -980,7 +981,8 @@ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
63 .offset = PCI_PM_CTRL,
64 .size = 2,
65 .init_val = 0x0008,
66- .ro_mask = 0xE1FC,
67+ .res_mask = 0x00F0,
68+ .ro_mask = 0xE10C,
69 .emu_mask = 0x810B,
70 .init = xen_pt_common_reg_init,
71 .u.w.read = xen_pt_word_reg_read,
72@@ -1268,7 +1270,8 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
73 .offset = PCI_MSI_FLAGS,
74 .size = 2,
75 .init_val = 0x0000,
76- .ro_mask = 0xFF8E,
77+ .res_mask = 0xFE00,
78+ .ro_mask = 0x018E,
79 .emu_mask = 0x017E,
80 .init = xen_pt_msgctrl_reg_init,
81 .u.w.read = xen_pt_word_reg_read,
82@@ -1446,7 +1449,8 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
83 .offset = PCI_MSI_FLAGS,
84 .size = 2,
85 .init_val = 0x0000,
86- .ro_mask = 0x3FFF,
87+ .res_mask = 0x3800,
88+ .ro_mask = 0x07FF,
89 .emu_mask = 0x0000,
90 .init = xen_pt_msixctrl_reg_init,
91 .u.w.read = xen_pt_word_reg_read,
92--
932.1.4
94
diff --git a/meta/recipes-devtools/qemu/qemu/10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch b/meta/recipes-devtools/qemu/qemu/10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch
new file mode 100644
index 0000000000..f30b40a93e
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch
@@ -0,0 +1,77 @@
1Upstream-Status: Backport
2
3Signed-off-by: Kai Kang <kai.kang@windriver.com>
4
5From a88a3f887181605f4487a22bdfb7d87ffafde5d9 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: add a few PCI config space field descriptions
9Bug-Debian: http://bugs.debian.org/787547
10
11Since the next patch will turn all not explicitly described fields
12read-only by default, those fields that have guest writable bits need
13to be given explicit descriptors.
14
15This is a preparatory patch for XSA-131.
16
17Signed-off-by: Jan Beulich <jbeulich@suse.com>
18---
19 hw/xen/xen_pt_config_init.c | 28 ++++++++++++++++++++++++++++
20 1 file changed, 28 insertions(+)
21
22diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
23index efd8bac..19f926b 100644
24--- a/hw/xen/xen_pt_config_init.c
25+++ b/hw/xen/xen_pt_config_init.c
26@@ -754,6 +754,15 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
27 .u.b.write = xen_pt_byte_reg_write,
28 },
29 {
30+ .offset = PCI_VPD_ADDR,
31+ .size = 2,
32+ .ro_mask = 0x0003,
33+ .emu_mask = 0x0003,
34+ .init = xen_pt_common_reg_init,
35+ .u.w.read = xen_pt_word_reg_read,
36+ .u.w.write = xen_pt_word_reg_write,
37+ },
38+ {
39 .size = 0,
40 },
41 };
42@@ -889,6 +898,16 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
43 .u.w.read = xen_pt_word_reg_read,
44 .u.w.write = xen_pt_word_reg_write,
45 },
46+ /* Device Status reg */
47+ {
48+ .offset = PCI_EXP_DEVSTA,
49+ .size = 2,
50+ .res_mask = 0xFFC0,
51+ .ro_mask = 0x0030,
52+ .init = xen_pt_common_reg_init,
53+ .u.w.read = xen_pt_word_reg_read,
54+ .u.w.write = xen_pt_word_reg_write,
55+ },
56 /* Link Control reg */
57 {
58 .offset = PCI_EXP_LNKCTL,
59@@ -900,6 +919,15 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
60 .u.w.read = xen_pt_word_reg_read,
61 .u.w.write = xen_pt_word_reg_write,
62 },
63+ /* Link Status reg */
64+ {
65+ .offset = PCI_EXP_LNKSTA,
66+ .size = 2,
67+ .ro_mask = 0x3FFF,
68+ .init = xen_pt_common_reg_init,
69+ .u.w.read = xen_pt_word_reg_read,
70+ .u.w.write = xen_pt_word_reg_write,
71+ },
72 /* Device Control 2 reg */
73 {
74 .offset = 0x28,
75--
762.1.4
77
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
new file mode 100644
index 0000000000..5bfcf5e166
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch
@@ -0,0 +1,137 @@
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
diff --git a/meta/recipes-devtools/qemu/qemu_2.3.0.bb b/meta/recipes-devtools/qemu/qemu_2.3.0.bb
index 4782941f52..ec1b101998 100644
--- a/meta/recipes-devtools/qemu/qemu_2.3.0.bb
+++ b/meta/recipes-devtools/qemu/qemu_2.3.0.bb
@@ -7,7 +7,18 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
7 file://qemu-enlarge-env-entry-size.patch \ 7 file://qemu-enlarge-env-entry-size.patch \
8 file://Qemu-Arm-versatilepb-Add-memory-size-checking.patch \ 8 file://Qemu-Arm-versatilepb-Add-memory-size-checking.patch \
9 file://qemu-CVE-2015-3456.patch \ 9 file://qemu-CVE-2015-3456.patch \
10 " 10 file://01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch \
11 file://02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch \
12 file://03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch \
13 file://04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch \
14 file://05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch \
15 file://06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch \
16 file://07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch \
17 file://08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch \
18 file://09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch \
19 file://10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch \
20 file://11-xen-pt-unknown-PCI-config-space-fields-should-be-readonly-CVE-2015-4106.patch \
21 "
11SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" 22SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
12SRC_URI[md5sum] = "2fab3ea4460de9b57192e5b8b311f221" 23SRC_URI[md5sum] = "2fab3ea4460de9b57192e5b8b311f221"
13SRC_URI[sha256sum] = "b6bab7f763d5be73e7cb5ee7d4c8365b7a8df2972c52fa5ded18893bd8281588" 24SRC_URI[sha256sum] = "b6bab7f763d5be73e7cb5ee7d4c8365b7a8df2972c52fa5ded18893bd8281588"