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 | 265 |
1 files changed, 265 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..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 @@ | |||
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 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
31 | index 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 | -- | ||
264 | 2.1.4 | ||
265 | |||