summaryrefslogtreecommitdiffstats
path: root/xen-pciback-limit-guest-control-of-command-register.patch
diff options
context:
space:
mode:
Diffstat (limited to 'xen-pciback-limit-guest-control-of-command-register.patch')
-rw-r--r--xen-pciback-limit-guest-control-of-command-register.patch156
1 files changed, 0 insertions, 156 deletions
diff --git a/xen-pciback-limit-guest-control-of-command-register.patch b/xen-pciback-limit-guest-control-of-command-register.patch
deleted file mode 100644
index 87600462d..000000000
--- a/xen-pciback-limit-guest-control-of-command-register.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-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
-