diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch | 263 |
1 files changed, 263 insertions, 0 deletions
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..f8308d8619 --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch | |||
@@ -0,0 +1,263 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 0e7ef22136955169a0fd03c4e41af95662352733 Mon Sep 17 00:00:00 2001 | ||
6 | From: Jan Beulich <jbeulich@suse.com> | ||
7 | Date: Tue, 2 Jun 2015 15:07:01 +0000 | ||
8 | Subject: xen/pt: split out calculation of throughable mask in | ||
9 | PCI config space handling | ||
10 | Bug-Debian: http://bugs.debian.org/787547 | ||
11 | |||
12 | This is just to avoid having to adjust that calculation later in | ||
13 | multiple places. | ||
14 | |||
15 | Note that including ->ro_mask in get_throughable_mask()'s calculation | ||
16 | is only an apparent (i.e. benign) behavioral change: For r/o fields it | ||
17 | doesn't matter > whether they get passed through - either the same flag | ||
18 | is also set in emu_mask (then there's no change at all) or the field is | ||
19 | r/o in hardware (and hence a write won't change it anyway). | ||
20 | |||
21 | This is a preparatory patch for XSA-131. | ||
22 | |||
23 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
24 | Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | ||
25 | Reviewed-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 | |||
30 | Index: qemu-2.2.0/hw/xen/xen_pt_config_init.c | ||
31 | =================================================================== | ||
32 | --- qemu-2.2.0.orig/hw/xen/xen_pt_config_init.c | ||
33 | +++ qemu-2.2.0/hw/xen/xen_pt_config_init.c | ||
34 | @@ -95,6 +95,14 @@ XenPTReg *xen_pt_find_reg(XenPTRegGroup | ||
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(XenPCIP | ||
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(XenPCIP | ||
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(XenPCIP | ||
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 | @@ -309,7 +314,7 @@ static int xen_pt_cmd_reg_write(XenPCIPa | ||
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 | uint16_t emu_mask = reg->emu_mask; | ||
104 | |||
105 | if (s->is_virtfn) { | ||
106 | @@ -321,8 +326,6 @@ static int xen_pt_cmd_reg_write(XenPCIPa | ||
107 | cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); | ||
108 | |||
109 | /* create value for writing to I/O device register */ | ||
110 | - throughable_mask = ~emu_mask & valid_mask; | ||
111 | - | ||
112 | if (*val & PCI_COMMAND_INTX_DISABLE) { | ||
113 | throughable_mask |= PCI_COMMAND_INTX_DISABLE; | ||
114 | } else { | ||
115 | @@ -478,7 +481,6 @@ static int xen_pt_bar_reg_write(XenPCIPa | ||
116 | PCIDevice *d = &s->dev; | ||
117 | const PCIIORegion *r; | ||
118 | uint32_t writable_mask = 0; | ||
119 | - uint32_t throughable_mask = 0; | ||
120 | uint32_t bar_emu_mask = 0; | ||
121 | uint32_t bar_ro_mask = 0; | ||
122 | uint32_t r_size = 0; | ||
123 | @@ -535,8 +537,7 @@ static int xen_pt_bar_reg_write(XenPCIPa | ||
124 | } | ||
125 | |||
126 | /* create value for writing to I/O device register */ | ||
127 | - throughable_mask = ~bar_emu_mask & valid_mask; | ||
128 | - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
129 | + *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | @@ -550,9 +551,8 @@ static int xen_pt_exp_rom_bar_reg_write( | ||
134 | XenPTRegion *base = NULL; | ||
135 | PCIDevice *d = (PCIDevice *)&s->dev; | ||
136 | uint32_t writable_mask = 0; | ||
137 | - uint32_t throughable_mask = 0; | ||
138 | + uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); | ||
139 | pcibus_t r_size = 0; | ||
140 | - uint32_t bar_emu_mask = 0; | ||
141 | uint32_t bar_ro_mask = 0; | ||
142 | |||
143 | r_size = d->io_regions[PCI_ROM_SLOT].size; | ||
144 | @@ -561,7 +561,6 @@ static int xen_pt_exp_rom_bar_reg_write( | ||
145 | r_size = xen_pt_get_emul_size(base->bar_flag, r_size); | ||
146 | |||
147 | /* set emulate mask and read-only mask */ | ||
148 | - bar_emu_mask = reg->emu_mask; | ||
149 | bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; | ||
150 | |||
151 | /* modify emulate register */ | ||
152 | @@ -569,7 +568,6 @@ static int xen_pt_exp_rom_bar_reg_write( | ||
153 | cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); | ||
154 | |||
155 | /* create value for writing to I/O device register */ | ||
156 | - throughable_mask = ~bar_emu_mask & valid_mask; | ||
157 | *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
158 | |||
159 | return 0; | ||
160 | @@ -964,14 +962,13 @@ static int xen_pt_pmcsr_reg_write(XenPCI | ||
161 | { | ||
162 | XenPTRegInfo *reg = cfg_entry->reg; | ||
163 | uint16_t writable_mask = 0; | ||
164 | - uint16_t throughable_mask = 0; | ||
165 | + uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); | ||
166 | |||
167 | /* modify emulate register */ | ||
168 | writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; | ||
169 | cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); | ||
170 | |||
171 | /* create value for writing to I/O device register */ | ||
172 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
173 | *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS, | ||
174 | throughable_mask); | ||
175 | |||
176 | @@ -1060,7 +1057,7 @@ static int xen_pt_msgctrl_reg_write(XenP | ||
177 | XenPTRegInfo *reg = cfg_entry->reg; | ||
178 | XenPTMSI *msi = s->msi; | ||
179 | uint16_t writable_mask = 0; | ||
180 | - uint16_t throughable_mask = 0; | ||
181 | + uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); | ||
182 | |||
183 | /* Currently no support for multi-vector */ | ||
184 | if (*val & PCI_MSI_FLAGS_QSIZE) { | ||
185 | @@ -1073,7 +1070,6 @@ static int xen_pt_msgctrl_reg_write(XenP | ||
186 | msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; | ||
187 | |||
188 | /* create value for writing to I/O device register */ | ||
189 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
190 | *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
191 | |||
192 | /* update MSI */ | ||
193 | @@ -1185,7 +1181,6 @@ static int xen_pt_msgaddr32_reg_write(Xe | ||
194 | { | ||
195 | XenPTRegInfo *reg = cfg_entry->reg; | ||
196 | uint32_t writable_mask = 0; | ||
197 | - uint32_t throughable_mask = 0; | ||
198 | uint32_t old_addr = cfg_entry->data; | ||
199 | |||
200 | /* modify emulate register */ | ||
201 | @@ -1194,8 +1189,7 @@ static int xen_pt_msgaddr32_reg_write(Xe | ||
202 | s->msi->addr_lo = cfg_entry->data; | ||
203 | |||
204 | /* create value for writing to I/O device register */ | ||
205 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
206 | - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
207 | + *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); | ||
208 | |||
209 | /* update MSI */ | ||
210 | if (cfg_entry->data != old_addr) { | ||
211 | @@ -1213,7 +1207,6 @@ static int xen_pt_msgaddr64_reg_write(Xe | ||
212 | { | ||
213 | XenPTRegInfo *reg = cfg_entry->reg; | ||
214 | uint32_t writable_mask = 0; | ||
215 | - uint32_t throughable_mask = 0; | ||
216 | uint32_t old_addr = cfg_entry->data; | ||
217 | |||
218 | /* check whether the type is 64 bit or not */ | ||
219 | @@ -1230,8 +1223,7 @@ static int xen_pt_msgaddr64_reg_write(Xe | ||
220 | s->msi->addr_hi = cfg_entry->data; | ||
221 | |||
222 | /* create value for writing to I/O device register */ | ||
223 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
224 | - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
225 | + *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); | ||
226 | |||
227 | /* update MSI */ | ||
228 | if (cfg_entry->data != old_addr) { | ||
229 | @@ -1253,7 +1245,6 @@ static int xen_pt_msgdata_reg_write(XenP | ||
230 | XenPTRegInfo *reg = cfg_entry->reg; | ||
231 | XenPTMSI *msi = s->msi; | ||
232 | uint16_t writable_mask = 0; | ||
233 | - uint16_t throughable_mask = 0; | ||
234 | uint16_t old_data = cfg_entry->data; | ||
235 | uint32_t offset = reg->offset; | ||
236 | |||
237 | @@ -1271,8 +1262,7 @@ static int xen_pt_msgdata_reg_write(XenP | ||
238 | msi->data = cfg_entry->data; | ||
239 | |||
240 | /* create value for writing to I/O device register */ | ||
241 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
242 | - *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
243 | + *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); | ||
244 | |||
245 | /* update MSI */ | ||
246 | if (cfg_entry->data != old_data) { | ||
247 | @@ -1434,7 +1424,7 @@ static int xen_pt_msixctrl_reg_write(Xen | ||
248 | { | ||
249 | XenPTRegInfo *reg = cfg_entry->reg; | ||
250 | uint16_t writable_mask = 0; | ||
251 | - uint16_t throughable_mask = 0; | ||
252 | + uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); | ||
253 | int debug_msix_enabled_old; | ||
254 | |||
255 | /* modify emulate register */ | ||
256 | @@ -1442,7 +1432,6 @@ static int xen_pt_msixctrl_reg_write(Xen | ||
257 | cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); | ||
258 | |||
259 | /* create value for writing to I/O device register */ | ||
260 | - throughable_mask = ~reg->emu_mask & valid_mask; | ||
261 | *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); | ||
262 | |||
263 | /* update MSI-X */ | ||