diff options
Diffstat (limited to 'meta/recipes-devtools/qemu')
14 files changed, 3 insertions, 1387 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 deleted file mode 100644 index 42a496042a..0000000000 --- a/meta/recipes-devtools/qemu/qemu/01-xen-properly-gate-host-writes-of-modified-PCI-CFG-contents-CVE-2015-4103.patch +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
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 | |||
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 deleted file mode 100644 index 252bf0223c..0000000000 --- a/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch +++ /dev/null | |||
@@ -1,194 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 7611dae8a69f0f1775ba1a9a942961c2aa10d88e 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: don't allow guest to control MSI mask register | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | It's being used by the hypervisor. For now simply mimic a device not | ||
12 | capable of masking, and fully emulate any accesses a guest may issue | ||
13 | nevertheless as simple reads/writes without side effects. | ||
14 | |||
15 | This is XSA-129. | ||
16 | |||
17 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
18 | Reviewed-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 | |||
25 | diff --git a/hw/pci/msi.c b/hw/pci/msi.c | ||
26 | index 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 | |||
40 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
41 | index 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 | }, | ||
177 | diff --git a/include/hw/pci/pci_regs.h b/include/hw/pci/pci_regs.h | ||
178 | index 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 | -- | ||
193 | 2.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 deleted file mode 100644 index 8bb2230333..0000000000 --- a/meta/recipes-devtools/qemu/qemu/03-xen-MSI-X-limit-error-messages-CVE-2015-4105.patch +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From b38ec5ee7a581776bbce0bdaecb397632c3c4791 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/MSI-X: limit error messages | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | Limit error messages resulting from bad guest behavior to avoid allowing | ||
12 | the guest to cause the control domain's disk to fill. | ||
13 | |||
14 | The first message in pci_msix_write() can simply be deleted, as this | ||
15 | is indeed bad guest behavior, but such out of bounds writes don't | ||
16 | really need to be logged. | ||
17 | |||
18 | The second one is more problematic, as there guest behavior may only | ||
19 | appear to be wrong: For one, the old logic didn't take the mask-all bit | ||
20 | into account. And then this shouldn't depend on host device state (i.e. | ||
21 | the host may have masked the entry without the guest having done so). | ||
22 | Plus these writes shouldn't be dropped even when an entry is unmasked. | ||
23 | Instead, if they can't be made take effect right away, they should take | ||
24 | effect on the next unmasking or enabling operation - the specification | ||
25 | explicitly describes such caching behavior. Until we can validly drop | ||
26 | the message (implementing such caching/latching behavior), issue the | ||
27 | message just once per MSI-X table entry. | ||
28 | |||
29 | Note that the log message in pci_msix_read() similar to the one being | ||
30 | removed here is not an issue: "addr" being of unsigned type, and the | ||
31 | maximum size of the MSI-X table being 32k, entry_nr simply can't be | ||
32 | negative and hence the conditonal guarding issuing of the message will | ||
33 | never be true. | ||
34 | |||
35 | This is XSA-130. | ||
36 | |||
37 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
38 | Reviewed-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 | |||
44 | diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h | ||
45 | index 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; | ||
56 | diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c | ||
57 | index 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 | -- | ||
89 | 2.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 deleted file mode 100644 index 87fb7f6fb7..0000000000 --- a/meta/recipes-devtools/qemu/qemu/04-xen-MSI-dont-open-code-pass-through-of-enable-bit-mod-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From d1d35cf4ffb6a60a356193397919e83306d0bb74 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/MSI: don't open-code pass-through of enable bit modifications | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | Without this the actual XSA-131 fix would cause the enable bit to not | ||
12 | get set anymore (due to the write back getting suppressed there based | ||
13 | on the OR of emu_mask, ro_mask, and res_mask). | ||
14 | |||
15 | Note that the fiddling with the enable bit shouldn't really be done by | ||
16 | qemu, but making this work right (via libxc and the hypervisor) will | ||
17 | require more extensive changes, which can be postponed until after the | ||
18 | security issue got addressed. | ||
19 | |||
20 | This is a preparatory patch for XSA-131. | ||
21 | |||
22 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
23 | Acked-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 | |||
28 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
29 | index 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 | -- | ||
75 | 2.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 deleted file mode 100644 index e9e4fccb4d..0000000000 --- a/meta/recipes-devtools/qemu/qemu/05-xen-pt-consolidate-PM-capability-emu_mask-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From d61bb2482dc0c7426f451f23ba7e2748ae2cc06d 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: consolidate PM capability emu_mask | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing | ||
12 | PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local | ||
13 | emu_mask variable - we can have the same effect by setting the field | ||
14 | descriptor's emu_mask member suitably right away. Note that | ||
15 | xen_pt_pmcsr_reg_write() is being retained in order to allow later | ||
16 | patches to be less intrusive. | ||
17 | |||
18 | This is a preparatory patch for XSA-131. | ||
19 | |||
20 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
21 | Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | ||
22 | Acked-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 | |||
27 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
28 | index 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 | -- | ||
85 | 2.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 deleted file mode 100644 index 37758cdd58..0000000000 --- a/meta/recipes-devtools/qemu/qemu/06-xen-pt-correctly-handle-PM-status-bit-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From c4ff1e68c621928abc680266cad0a451686c403b 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: correctly handle PM status bit | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C | ||
12 | nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS). | ||
13 | |||
14 | This is a preparatory patch for XSA-131. | ||
15 | |||
16 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
17 | Reviewed-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 | |||
22 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
23 | index 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 | -- | ||
37 | 2.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 deleted file mode 100644 index 28b75922d7..0000000000 --- a/meta/recipes-devtools/qemu/qemu/07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
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 | |||
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 deleted file mode 100644 index 4236a1295f..0000000000 --- a/meta/recipes-devtools/qemu/qemu/08-xen-pt-mark-all-PCIe-capability-bits-read-only-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 45ebe3916ab16f859ed930e92fbd52d84d5dcdaf 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: mark all PCIe capability bits read-only | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read- | ||
12 | only to avoid unintended write-back (just a precaution, the field ought | ||
13 | to be read-only in hardware). | ||
14 | |||
15 | This is a preparatory patch for XSA-131. | ||
16 | |||
17 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
18 | Reviewed-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 | |||
23 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
24 | index 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 | -- | ||
37 | 2.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 deleted file mode 100644 index 99b8ba4904..0000000000 --- a/meta/recipes-devtools/qemu/qemu/09-xen-pt-mark-reserved-bits-in-PCI-config-space-fields-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 0ad3393ad032f76e88b4dbd04d36ad84dff75dd6 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: mark reserved bits in PCI config space fields | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | The 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 | ||
14 | and reserved fields must be similarly protected from guest access in | ||
15 | default mode, but the guest should be allowed access to them in | ||
16 | permissive mode). | ||
17 | |||
18 | This is a preparatory patch for XSA-131. | ||
19 | |||
20 | Signed-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 | |||
26 | diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h | ||
27 | index 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) */ | ||
39 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
40 | index 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 | -- | ||
93 | 2.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 deleted file mode 100644 index f30b40a93e..0000000000 --- a/meta/recipes-devtools/qemu/qemu/10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From a88a3f887181605f4487a22bdfb7d87ffafde5d9 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: add a few PCI config space field descriptions | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | Since the next patch will turn all not explicitly described fields | ||
12 | read-only by default, those fields that have guest writable bits need | ||
13 | to be given explicit descriptors. | ||
14 | |||
15 | This is a preparatory patch for XSA-131. | ||
16 | |||
17 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
18 | --- | ||
19 | hw/xen/xen_pt_config_init.c | 28 ++++++++++++++++++++++++++++ | ||
20 | 1 file changed, 28 insertions(+) | ||
21 | |||
22 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
23 | index 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 | -- | ||
76 | 2.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 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 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From c25bbf1545a53ac051f9e51d4140e397660c10ae 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: unknown PCI config space fields should be read-only | ||
9 | Bug-Debian: http://bugs.debian.org/787547 | ||
10 | |||
11 | ... by default. Add a per-device "permissive" mode similar to pciback's | ||
12 | to allow restoring previous behavior (and hence break security again, | ||
13 | i.e. should be used only for trusted guests). | ||
14 | |||
15 | This is part of XSA-131. | ||
16 | |||
17 | Signed-off-by: Jan Beulich <jbeulich@suse.com> | ||
18 | Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> | ||
19 | Reviewed-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 | |||
26 | diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c | ||
27 | index 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 | |||
107 | diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h | ||
108 | index 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; | ||
120 | diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c | ||
121 | index 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 | -- | ||
136 | 2.1.4 | ||
137 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/qemu-CVE-2015-3456.patch b/meta/recipes-devtools/qemu/qemu/qemu-CVE-2015-3456.patch deleted file mode 100644 index f05441fce6..0000000000 --- a/meta/recipes-devtools/qemu/qemu/qemu-CVE-2015-3456.patch +++ /dev/null | |||
@@ -1,92 +0,0 @@ | |||
1 | qemu: CVE-2015-3456 | ||
2 | |||
3 | the patch comes from: | ||
4 | https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-3456 | ||
5 | http://git.qemu.org/?p=qemu.git;a=commit;h=e907746266721f305d67bc0718795fedee2e824c | ||
6 | |||
7 | fdc: force the fifo access to be in bounds of the allocated buffer | ||
8 | |||
9 | During processing of certain commands such as FD_CMD_READ_ID and | ||
10 | FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could | ||
11 | get out of bounds leading to memory corruption with values coming | ||
12 | from the guest. | ||
13 | |||
14 | Fix this by making sure that the index is always bounded by the | ||
15 | allocated memory. | ||
16 | |||
17 | This is CVE-2015-3456. | ||
18 | |||
19 | Signed-off-by: Petr Matousek <pmatouse@redhat.com> | ||
20 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
21 | Signed-off-by: John Snow <jsnow@redhat.com> | ||
22 | Signed-off-by: Li Wang <li.wang@windriver.com> | ||
23 | |||
24 | Upstream-Status: Backport | ||
25 | |||
26 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
27 | --- | ||
28 | hw/block/fdc.c | 17 +++++++++++------ | ||
29 | 1 file changed, 11 insertions(+), 6 deletions(-) | ||
30 | |||
31 | diff --git a/hw/block/fdc.c b/hw/block/fdc.c | ||
32 | index 490d127..045459e 100644 | ||
33 | --- a/hw/block/fdc.c | ||
34 | +++ b/hw/block/fdc.c | ||
35 | @@ -1436,7 +1436,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) | ||
36 | { | ||
37 | FDrive *cur_drv; | ||
38 | uint32_t retval = 0; | ||
39 | - int pos; | ||
40 | + uint32_t pos; | ||
41 | |||
42 | cur_drv = get_cur_drv(fdctrl); | ||
43 | fdctrl->dsr &= ~FD_DSR_PWRDOWN; | ||
44 | @@ -1445,8 +1445,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl) | ||
45 | return 0; | ||
46 | } | ||
47 | pos = fdctrl->data_pos; | ||
48 | + pos %= FD_SECTOR_LEN; | ||
49 | if (fdctrl->msr & FD_MSR_NONDMA) { | ||
50 | - pos %= FD_SECTOR_LEN; | ||
51 | if (pos == 0) { | ||
52 | if (fdctrl->data_pos != 0) | ||
53 | if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { | ||
54 | @@ -1790,10 +1790,13 @@ static void fdctrl_handle_option(FDCtrl *fdctrl, int direction) | ||
55 | static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction) | ||
56 | { | ||
57 | FDrive *cur_drv = get_cur_drv(fdctrl); | ||
58 | + uint32_t pos; | ||
59 | |||
60 | - if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) { | ||
61 | + pos = fdctrl->data_pos - 1; | ||
62 | + pos %= FD_SECTOR_LEN; | ||
63 | + if (fdctrl->fifo[pos] & 0x80) { | ||
64 | /* Command parameters done */ | ||
65 | - if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) { | ||
66 | + if (fdctrl->fifo[pos] & 0x40) { | ||
67 | fdctrl->fifo[0] = fdctrl->fifo[1]; | ||
68 | fdctrl->fifo[2] = 0; | ||
69 | fdctrl->fifo[3] = 0; | ||
70 | @@ -1893,7 +1896,7 @@ static uint8_t command_to_handler[256]; | ||
71 | static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) | ||
72 | { | ||
73 | FDrive *cur_drv; | ||
74 | - int pos; | ||
75 | + uint32_t pos; | ||
76 | |||
77 | /* Reset mode */ | ||
78 | if (!(fdctrl->dor & FD_DOR_nRESET)) { | ||
79 | @@ -1941,7 +1944,9 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) | ||
80 | } | ||
81 | |||
82 | FLOPPY_DPRINTF("%s: %02x\n", __func__, value); | ||
83 | - fdctrl->fifo[fdctrl->data_pos++] = value; | ||
84 | + pos = fdctrl->data_pos++; | ||
85 | + pos %= FD_SECTOR_LEN; | ||
86 | + fdctrl->fifo[pos] = value; | ||
87 | if (fdctrl->data_pos == fdctrl->data_len) { | ||
88 | /* We now have all parameters | ||
89 | * and will be able to treat the command | ||
90 | -- | ||
91 | 1.7.9.5 | ||
92 | |||
diff --git a/meta/recipes-devtools/qemu/qemu/qemu-fix-CVE-2015-3209.patch b/meta/recipes-devtools/qemu/qemu/qemu-fix-CVE-2015-3209.patch deleted file mode 100644 index d2dbb94e0a..0000000000 --- a/meta/recipes-devtools/qemu/qemu/qemu-fix-CVE-2015-3209.patch +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | Upstream-Status: Backport | ||
2 | |||
3 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
4 | |||
5 | From 9f7c594c006289ad41169b854d70f5da6e400a2a Mon Sep 17 00:00:00 2001 | ||
6 | From: Petr Matousek <pmatouse@redhat.com> | ||
7 | Date: Sun, 24 May 2015 10:53:44 +0200 | ||
8 | Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx | ||
9 | |||
10 | 4096 is the maximum length per TMD and it is also currently the size of | ||
11 | the relay buffer pcnet driver uses for sending the packet data to QEMU | ||
12 | for further processing. With packet spanning multiple TMDs it can | ||
13 | happen that the overall packet size will be bigger than sizeof(buffer), | ||
14 | which results in memory corruption. | ||
15 | |||
16 | Fix this by only allowing to queue maximum sizeof(buffer) bytes. | ||
17 | |||
18 | This is CVE-2015-3209. | ||
19 | |||
20 | [Fixed 3-space indentation to QEMU's 4-space coding standard. | ||
21 | --Stefan] | ||
22 | |||
23 | Signed-off-by: Petr Matousek <pmatouse@redhat.com> | ||
24 | Reported-by: Matt Tait <matttait@google.com> | ||
25 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
26 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
27 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
28 | --- | ||
29 | hw/net/pcnet.c | 8 ++++++++ | ||
30 | 1 file changed, 8 insertions(+) | ||
31 | |||
32 | diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c | ||
33 | index bdfd38f..68b9981 100644 | ||
34 | --- a/hw/net/pcnet.c | ||
35 | +++ b/hw/net/pcnet.c | ||
36 | @@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s) | ||
37 | } | ||
38 | |||
39 | bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); | ||
40 | + | ||
41 | + /* if multi-tmd packet outsizes s->buffer then skip it silently. | ||
42 | + Note: this is not what real hw does */ | ||
43 | + if (s->xmit_pos + bcnt > sizeof(s->buffer)) { | ||
44 | + s->xmit_pos = -1; | ||
45 | + goto txdone; | ||
46 | + } | ||
47 | + | ||
48 | s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), | ||
49 | s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); | ||
50 | s->xmit_pos += bcnt; | ||
51 | -- | ||
52 | 2.4.1 | ||
53 | |||
diff --git a/meta/recipes-devtools/qemu/qemu_2.4.0-rc4.bb b/meta/recipes-devtools/qemu/qemu_2.4.0.bb index 1964a5047f..5e5f786b10 100644 --- a/meta/recipes-devtools/qemu/qemu_2.4.0-rc4.bb +++ b/meta/recipes-devtools/qemu/qemu_2.4.0.bb | |||
@@ -7,13 +7,9 @@ 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 | " | 9 | " |
10 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BPN}-${REALPV}.tar.bz2" | 10 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" |
11 | SRC_URI[md5sum] = "0e9c00b15d383043ce888f7bf17308c9" | 11 | SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" |
12 | SRC_URI[sha256sum] = "724bc17d29babe2b55107c76af7cd67e162857958a3bfe2f34bb9776f1f5f4b3" | 12 | SRC_URI[sha256sum] = "72b0b991bbcc540663a019e1e8c4f714053b691dda32c9b9ee80b25f367e6620" |
13 | |||
14 | S="${WORKDIR}/${BPN}-${REALPV}" | ||
15 | REALPV = "2.4.0-rc4" | ||
16 | PV = "2.3.99+${REALPV}" | ||
17 | 13 | ||
18 | COMPATIBLE_HOST_class-target_mips64 = "null" | 14 | COMPATIBLE_HOST_class-target_mips64 = "null" |
19 | 15 | ||