diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch | 140 |
1 files changed, 140 insertions, 0 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 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 5c83b2f5b4b956e91dd6e5711f14df7ab800aefb Mon Sep 17 00:00:00 2001 | ||
6 | From: Jan Beulich <jbeulich@suse.com> | ||
7 | Date: Tue, 2 Jun 2015 15:07:00 +0000 | ||
8 | Subject: xen: properly gate host writes of modified PCI CFG contents | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | The old logic didn't work as intended when an access spanned multiple | ||
12 | fields (for example a 32-bit access to the location of the MSI Message | ||
13 | Data field with the high 16 bits not being covered by any known field). | ||
14 | Remove it and derive which fields not to write to from the accessed | ||
15 | fields' emulation masks: When they're all ones, there's no point in | ||
16 | doing any host write. | ||
17 | |||
18 | This fixes a secondary issue at once: We obviously shouldn't make any | ||
19 | host write attempt when already the host read failed. | ||
20 | |||
21 | This is XSA-128. | ||
22 | |||
23 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
24 | Reviewed-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 | |||
31 | diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c | ||
32 | index 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); | ||
89 | diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h | ||
90 | index 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 */ | ||
102 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
103 | index 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 | -- | ||
139 | 2.1.4 | ||
140 | |||