xen/vpci: CFI hardening

Control Flow Integrity schemes use toolchain and optionally hardware support
to help protect against call/jump/return oriented programming attacks.

Use cf_check to annotate function pointer targets for the toolchain.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2022-02-23 15:33:43 +00:00
1 parent ef0434ae38
commit 4ed7d5525f
5 files changed
+52 -52

No files matched your search

+9 -9
View File
@@ -33,8 +33,8 @@ struct map_data {
bool map;
};
static int map_range(unsigned long s, unsigned long e, void *data,
unsigned long *c)
static int cf_check map_range(
unsigned long s, unsigned long e, void *data, unsigned long *c)
{
const struct map_data *map = data;
int rc;
@@ -332,8 +332,8 @@ static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_only)
return 0;
}
static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t cmd, void *data)
static void cf_check cmd_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t cmd, void *data)
{
uint16_t current_cmd = pci_conf_read16(pdev->sbdf, reg);
@@ -353,8 +353,8 @@ static void cmd_write(const struct pci_dev *pdev, unsigned int reg,
pci_conf_write16(pdev->sbdf, reg, cmd);
}
static void bar_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check bar_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_bar *bar = data;
bool hi = false;
@@ -397,8 +397,8 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
pci_conf_write32(pdev->sbdf, reg, val);
}
static void rom_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check rom_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_header *header = &pdev->vpci->header;
struct vpci_bar *rom = data;
@@ -445,7 +445,7 @@ static void rom_write(const struct pci_dev *pdev, unsigned int reg,
rom->addr = val & PCI_ROM_ADDRESS_MASK;
}
static int init_bars(struct pci_dev *pdev)
static int cf_check init_bars(struct pci_dev *pdev)
{
uint16_t cmd;
uint64_t addr, size;
+21 -21
View File
@@ -22,8 +22,8 @@
#include <asm/msi.h>
static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check control_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msi *msi = data;
@@ -34,8 +34,8 @@ static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg,
(msi->address64 ? PCI_MSI_FLAGS_64BIT : 0);
}
static void control_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check control_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msi *msi = data;
unsigned int vectors = min_t(uint8_t,
@@ -89,16 +89,16 @@ static void update_msi(const struct pci_dev *pdev, struct vpci_msi *msi)
}
/* Handlers for the address field (32bit or low part of a 64bit address). */
static uint32_t address_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check address_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msi *msi = data;
return msi->address;
}
static void address_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check address_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msi *msi = data;
@@ -110,16 +110,16 @@ static void address_write(const struct pci_dev *pdev, unsigned int reg,
}
/* Handlers for the high part of a 64bit address field. */
static uint32_t address_hi_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check address_hi_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msi *msi = data;
return msi->address >> 32;
}
static void address_hi_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check address_hi_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msi *msi = data;
@@ -131,16 +131,16 @@ static void address_hi_write(const struct pci_dev *pdev, unsigned int reg,
}
/* Handlers for the data field. */
static uint32_t data_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check data_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msi *msi = data;
return msi->data;
}
static void data_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check data_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msi *msi = data;
@@ -150,16 +150,16 @@ static void data_write(const struct pci_dev *pdev, unsigned int reg,
}
/* Handlers for the MSI mask bits. */
static uint32_t mask_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check mask_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msi *msi = data;
return msi->mask;
}
static void mask_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check mask_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msi *msi = data;
uint32_t dmask = msi->mask ^ val;
@@ -182,7 +182,7 @@ static void mask_write(const struct pci_dev *pdev, unsigned int reg,
msi->mask = val;
}
static int init_msi(struct pci_dev *pdev)
static int cf_check init_msi(struct pci_dev *pdev)
{
uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
unsigned int pos = pci_find_cap_offset(pdev->seg, pdev->bus, slot, func,
+10 -10
View File
@@ -27,8 +27,8 @@
((addr) >= vmsix_table_addr(vpci, nr) && \
(addr) < vmsix_table_addr(vpci, nr) + vmsix_table_size(vpci, nr))
static uint32_t control_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check control_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
const struct vpci_msix *msix = data;
@@ -65,8 +65,8 @@ static void update_entry(struct vpci_msix_entry *entry,
entry->updated = false;
}
static void control_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check control_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
struct vpci_msix *msix = data;
bool new_masked = val & PCI_MSIX_FLAGS_MASKALL;
@@ -156,7 +156,7 @@ static struct vpci_msix *msix_find(const struct domain *d, unsigned long addr)
return NULL;
}
static int msix_accept(struct vcpu *v, unsigned long addr)
static int cf_check msix_accept(struct vcpu *v, unsigned long addr)
{
return !!msix_find(v->domain, addr);
}
@@ -182,8 +182,8 @@ static struct vpci_msix_entry *get_entry(struct vpci_msix *msix,
return &msix->entries[(addr - start) / PCI_MSIX_ENTRY_SIZE];
}
static int msix_read(struct vcpu *v, unsigned long addr, unsigned int len,
unsigned long *data)
static int cf_check msix_read(
struct vcpu *v, unsigned long addr, unsigned int len, unsigned long *data)
{
const struct domain *d = v->domain;
struct vpci_msix *msix = msix_find(d, addr);
@@ -259,8 +259,8 @@ static int msix_read(struct vcpu *v, unsigned long addr, unsigned int len,
return X86EMUL_OKAY;
}
static int msix_write(struct vcpu *v, unsigned long addr, unsigned int len,
unsigned long data)
static int cf_check msix_write(
struct vcpu *v, unsigned long addr, unsigned int len, unsigned long data)
{
const struct domain *d = v->domain;
struct vpci_msix *msix = msix_find(d, addr);
@@ -428,7 +428,7 @@ int vpci_make_msix_hole(const struct pci_dev *pdev)
return 0;
}
static int init_msix(struct pci_dev *pdev)
static int cf_check init_msix(struct pci_dev *pdev)
{
struct domain *d = pdev->domain;
uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
+8 -8
View File
@@ -106,25 +106,25 @@ static int vpci_register_cmp(const struct vpci_register *r1,
}
/* Dummy hooks, writes are ignored, reads return 1's */
static uint32_t vpci_ignored_read(const struct pci_dev *pdev, unsigned int reg,
void *data)
static uint32_t cf_check vpci_ignored_read(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
return ~(uint32_t)0;
}
static void vpci_ignored_write(const struct pci_dev *pdev, unsigned int reg,
uint32_t val, void *data)
static void cf_check vpci_ignored_write(
const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
{
}
uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
void *data)
uint32_t cf_check vpci_hw_read16(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
return pci_conf_read16(pdev->sbdf, reg);
}
uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
void *data)
uint32_t cf_check vpci_hw_read32(
const struct pci_dev *pdev, unsigned int reg, void *data)
{
return pci_conf_read32(pdev->sbdf, reg);
}
+4 -4
View File
@@ -46,10 +46,10 @@ void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
uint32_t data);
/* Passthrough handlers. */
uint32_t vpci_hw_read16(const struct pci_dev *pdev, unsigned int reg,
void *data);
uint32_t vpci_hw_read32(const struct pci_dev *pdev, unsigned int reg,
void *data);
uint32_t cf_check vpci_hw_read16(
const struct pci_dev *pdev, unsigned int reg, void *data);
uint32_t cf_check vpci_hw_read32(
const struct pci_dev *pdev, unsigned int reg, void *data);
/*
* Check for pending vPCI operations on this vcpu. Returns true if the vcpu
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.