diff options
author | Kai Kang <kai.kang@windriver.com> | 2015-06-18 17:02:42 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-09-01 21:19:41 +0100 |
commit | 328d35b53db61c86717c68cc564a790ccfa2956c (patch) | |
tree | 6feab80e4eb7b1df81c6d6fdad6977726ed0f442 /meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch | |
parent | 2adb210c8cc5a11bb899e7dc76c31159ff3d4116 (diff) | |
download | poky-328d35b53db61c86717c68cc564a790ccfa2956c.tar.gz |
qemu: backport patches to fix CVE issues
Backport patches to fix CVE-2015-4103, CVE-2015-4104, CVE-2015-4105 and
CVE-2015-4106. These patches are from debian, but they are originally
from:
http://git.qemu.org/?p=qemu.git;a=shortlog;h=c25bbf1
(From OE-Core master rev: 496b3ffba6755bb76709c88cf81399c9d23f830a)
(From OE-Core rev: 29746e78ca000f4464c8e0a1da55c77e02c651e4)
Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Refresh the following patches to apply cleanly to our qemu-2.2.0:
07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch b/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch new file mode 100644 index 0000000000..252bf0223c --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/02-xen-dont-allow-guest-to-control-MSI-mask-register-CVE-2015-4104.patch | |||
@@ -0,0 +1,194 @@ | |||
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 | |||