CVE-2015-2150 xen: NMIs triggerable by guests (rhbz 1196266 1200397)
This commit is contained in:
parent
00acd3eec4
commit
ac03c510f0
@ -651,6 +651,9 @@ Patch26162: Input-synaptics-remove-X1-Carbon-3rd-gen-from-the-to.patch
|
|||||||
Patch26163: Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
|
Patch26163: Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
|
||||||
Patch26164: Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
|
Patch26164: Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
|
||||||
|
|
||||||
|
#CVE-2015-2150 rhbz 1196266 1200397
|
||||||
|
Patch26165: xen-pciback-limit-guest-control-of-command-register.patch
|
||||||
|
|
||||||
# git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
|
# git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
|
||||||
Patch30000: kernel-arm64.patch
|
Patch30000: kernel-arm64.patch
|
||||||
|
|
||||||
@ -1406,6 +1409,9 @@ ApplyPatch Input-synaptics-remove-X1-Carbon-3rd-gen-from-the-to.patch
|
|||||||
ApplyPatch Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
|
ApplyPatch Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
|
||||||
ApplyPatch Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
|
ApplyPatch Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
|
||||||
|
|
||||||
|
#CVE-2015-2150 rhbz 1196266 1200397
|
||||||
|
ApplyPatch xen-pciback-limit-guest-control-of-command-register.patch
|
||||||
|
|
||||||
%if 0%{?aarch64patches}
|
%if 0%{?aarch64patches}
|
||||||
ApplyPatch kernel-arm64.patch
|
ApplyPatch kernel-arm64.patch
|
||||||
%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
|
%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
|
||||||
@ -2265,6 +2271,7 @@ fi
|
|||||||
%changelog
|
%changelog
|
||||||
* Wed Mar 11 2015 Josh Boyer <jwboyer@fedoraproject.org> - 4.0.0-0.rc3.git1.1
|
* Wed Mar 11 2015 Josh Boyer <jwboyer@fedoraproject.org> - 4.0.0-0.rc3.git1.1
|
||||||
- Linux v4.0-rc3-111-gaffb8172de39
|
- Linux v4.0-rc3-111-gaffb8172de39
|
||||||
|
- CVE-2015-2150 xen: NMIs triggerable by guests (rhbz 1196266 1200397)
|
||||||
- Patch series to fix Lenovo *40 and Carbon X1 touchpads (rhbz 1200777 1200778)
|
- Patch series to fix Lenovo *40 and Carbon X1 touchpads (rhbz 1200777 1200778)
|
||||||
- Revert commit that added bad rpath to cpupower (rhbz 1199312)
|
- Revert commit that added bad rpath to cpupower (rhbz 1199312)
|
||||||
- Reenable debugging options.
|
- Reenable debugging options.
|
||||||
|
156
xen-pciback-limit-guest-control-of-command-register.patch
Normal file
156
xen-pciback-limit-guest-control-of-command-register.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
From: Jan Beulich <JBeulich@suse.com>
|
||||||
|
Date: Wed, 11 Mar 2015 13:51:17 +0000
|
||||||
|
Subject: [PATCH] xen-pciback: limit guest control of command register
|
||||||
|
|
||||||
|
Otherwise the guest can abuse that control to cause e.g. PCIe
|
||||||
|
Unsupported Request responses (by disabling memory and/or I/O decoding
|
||||||
|
and subsequently causing [CPU side] accesses to the respective address
|
||||||
|
ranges), which (depending on system configuration) may be fatal to the
|
||||||
|
host.
|
||||||
|
|
||||||
|
Note that to alter any of the bits collected together as
|
||||||
|
PCI_COMMAND_GUEST permissive mode is now required to be enabled
|
||||||
|
globally or on the specific device.
|
||||||
|
|
||||||
|
This is CVE-2015-2150 / XSA-120.
|
||||||
|
|
||||||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||||
|
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
|
---
|
||||||
|
drivers/xen/xen-pciback/conf_space.c | 2 +-
|
||||||
|
drivers/xen/xen-pciback/conf_space.h | 2 +
|
||||||
|
drivers/xen/xen-pciback/conf_space_header.c | 61 +++++++++++++++++++++++------
|
||||||
|
3 files changed, 51 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
|
||||||
|
index 46ae0f9f02ad..75fe3d466515 100644
|
||||||
|
--- a/drivers/xen/xen-pciback/conf_space.c
|
||||||
|
+++ b/drivers/xen/xen-pciback/conf_space.c
|
||||||
|
@@ -16,7 +16,7 @@
|
||||||
|
#include "conf_space.h"
|
||||||
|
#include "conf_space_quirks.h"
|
||||||
|
|
||||||
|
-static bool permissive;
|
||||||
|
+bool permissive;
|
||||||
|
module_param(permissive, bool, 0644);
|
||||||
|
|
||||||
|
/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,
|
||||||
|
diff --git a/drivers/xen/xen-pciback/conf_space.h b/drivers/xen/xen-pciback/conf_space.h
|
||||||
|
index e56c934ad137..2e1d73d1d5d0 100644
|
||||||
|
--- a/drivers/xen/xen-pciback/conf_space.h
|
||||||
|
+++ b/drivers/xen/xen-pciback/conf_space.h
|
||||||
|
@@ -64,6 +64,8 @@ struct config_field_entry {
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
+extern bool permissive;
|
||||||
|
+
|
||||||
|
#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
|
||||||
|
|
||||||
|
/* Add fields to a device - the add_fields macro expects to get a pointer to
|
||||||
|
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
|
||||||
|
index c5ee82587e8c..2d7369391472 100644
|
||||||
|
--- a/drivers/xen/xen-pciback/conf_space_header.c
|
||||||
|
+++ b/drivers/xen/xen-pciback/conf_space_header.c
|
||||||
|
@@ -11,6 +11,10 @@
|
||||||
|
#include "pciback.h"
|
||||||
|
#include "conf_space.h"
|
||||||
|
|
||||||
|
+struct pci_cmd_info {
|
||||||
|
+ u16 val;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct pci_bar_info {
|
||||||
|
u32 val;
|
||||||
|
u32 len_val;
|
||||||
|
@@ -20,22 +24,36 @@ struct pci_bar_info {
|
||||||
|
#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
|
||||||
|
#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
|
||||||
|
|
||||||
|
-static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
|
||||||
|
+/* Bits guests are allowed to control in permissive mode. */
|
||||||
|
+#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
|
||||||
|
+ PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
|
||||||
|
+ PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
|
||||||
|
+
|
||||||
|
+static void *command_init(struct pci_dev *dev, int offset)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
- ret = xen_pcibk_read_config_word(dev, offset, value, data);
|
||||||
|
- if (!pci_is_enabled(dev))
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- for (i = 0; i < PCI_ROM_RESOURCE; i++) {
|
||||||
|
- if (dev->resource[i].flags & IORESOURCE_IO)
|
||||||
|
- *value |= PCI_COMMAND_IO;
|
||||||
|
- if (dev->resource[i].flags & IORESOURCE_MEM)
|
||||||
|
- *value |= PCI_COMMAND_MEMORY;
|
||||||
|
+ struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ if (!cmd)
|
||||||
|
+ return ERR_PTR(-ENOMEM);
|
||||||
|
+
|
||||||
|
+ err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
|
||||||
|
+ if (err) {
|
||||||
|
+ kfree(cmd);
|
||||||
|
+ return ERR_PTR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ return cmd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
|
||||||
|
+{
|
||||||
|
+ int ret = pci_read_config_word(dev, offset, value);
|
||||||
|
+ const struct pci_cmd_info *cmd = data;
|
||||||
|
+
|
||||||
|
+ *value &= PCI_COMMAND_GUEST;
|
||||||
|
+ *value |= cmd->val & ~PCI_COMMAND_GUEST;
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -43,6 +61,8 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
|
||||||
|
{
|
||||||
|
struct xen_pcibk_dev_data *dev_data;
|
||||||
|
int err;
|
||||||
|
+ u16 val;
|
||||||
|
+ struct pci_cmd_info *cmd = data;
|
||||||
|
|
||||||
|
dev_data = pci_get_drvdata(dev);
|
||||||
|
if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
|
||||||
|
@@ -83,6 +103,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ cmd->val = value;
|
||||||
|
+
|
||||||
|
+ if (!permissive && (!dev_data || !dev_data->permissive))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* Only allow the guest to control certain bits. */
|
||||||
|
+ err = pci_read_config_word(dev, offset, &val);
|
||||||
|
+ if (err || val == value)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ value &= PCI_COMMAND_GUEST;
|
||||||
|
+ value |= val & ~PCI_COMMAND_GUEST;
|
||||||
|
+
|
||||||
|
return pci_write_config_word(dev, offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -282,6 +315,8 @@ static const struct config_field header_common[] = {
|
||||||
|
{
|
||||||
|
.offset = PCI_COMMAND,
|
||||||
|
.size = 2,
|
||||||
|
+ .init = command_init,
|
||||||
|
+ .release = bar_release,
|
||||||
|
.u.w.read = command_read,
|
||||||
|
.u.w.write = command_write,
|
||||||
|
},
|
||||||
|
--
|
||||||
|
2.1.0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user