summaryrefslogtreecommitdiffstats
path: root/pcidev.c
diff options
context:
space:
mode:
authorYouness Alaoui <kakaroto@kakaroto.homelinux.net>2017-07-26 18:03:36 -0400
committerNico Huber <nico.h@gmx.de>2017-08-10 15:18:11 +0000
commita54ceb1dbe76e76ca8701dbda3e5baf011b16d6d (patch)
treef27ce3b104511a8b1598e77858cb42b41cb5e515 /pcidev.c
parent67d71792929f94d4638a3663f2fc19aea4918681 (diff)
downloadflashrom-a54ceb1dbe76e76ca8701dbda3e5baf011b16d6d.tar.gz
flashrom-a54ceb1dbe76e76ca8701dbda3e5baf011b16d6d.tar.bz2
flashrom-a54ceb1dbe76e76ca8701dbda3e5baf011b16d6d.zip
rpci: Use pci_dev struct pointer to avoid API breaks
The pci_dev structure is never meant to be used as is, but always as a pointer. By using the struct itself in undo_pci_write_data, we are risking data corruption, or buffer overflows if the structure size changes. This is especially apparent on my system where flashrom segfaults because I compile it with pciutils 3.3.0 and I run it on a system with pciutils 3.5.2. The struture size is different and causes a struct with the wrong size to be sent to the library, with invalid internal field values. This has been discovered and discussed in Change ID 18925 [1] [1] https://review.coreboot.org/#/c/18925/ Change-Id: Icde2e587992ba964d4ff92c33aa659850ba06298 Signed-off-by: Youness Alaoui <kakaroto@kakaroto.homelinux.net> Reviewed-on: https://review.coreboot.org/20784 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
Diffstat (limited to 'pcidev.c')
-rw-r--r--pcidev.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/pcidev.c b/pcidev.c
index 2c7806379..f4e554207 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -160,6 +160,7 @@ static int pcidev_shutdown(void *data)
return 1;
}
pci_cleanup(pacc);
+ pacc = NULL;
return 0;
}
@@ -259,7 +260,7 @@ enum pci_write_type {
};
struct undo_pci_write_data {
- struct pci_dev dev;
+ struct pci_dev *dev;
int reg;
enum pci_write_type type;
union {
@@ -272,22 +273,23 @@ struct undo_pci_write_data {
int undo_pci_write(void *p)
{
struct undo_pci_write_data *data = p;
- if (pacc == NULL) {
- msg_perr("%s: Tried to undo PCI writes without a valid PCI context!\n"
- "Please report a bug at flashrom@flashrom.org\n", __func__);
+ if (pacc == NULL || data->dev == NULL) {
+ msg_perr("%s: Tried to undo PCI writes without a valid PCI %s!\n"
+ "Please report a bug at flashrom@flashrom.org\n",
+ __func__, data->dev == NULL ? "device" : "context");
return 1;
}
msg_pdbg("Restoring PCI config space for %02x:%02x:%01x reg 0x%02x\n",
- data->dev.bus, data->dev.dev, data->dev.func, data->reg);
+ data->dev->bus, data->dev->dev, data->dev->func, data->reg);
switch (data->type) {
case pci_write_type_byte:
- pci_write_byte(&data->dev, data->reg, data->bytedata);
+ pci_write_byte(data->dev, data->reg, data->bytedata);
break;
case pci_write_type_word:
- pci_write_word(&data->dev, data->reg, data->worddata);
+ pci_write_word(data->dev, data->reg, data->worddata);
break;
case pci_write_type_long:
- pci_write_long(&data->dev, data->reg, data->longdata);
+ pci_write_long(data->dev, data->reg, data->longdata);
break;
}
/* p was allocated in register_undo_pci_write. */
@@ -303,7 +305,11 @@ int undo_pci_write(void *p)
msg_gerr("Out of memory!\n"); \
exit(1); \
} \
- undo_pci_write_data->dev = *a; \
+ if (pacc) \
+ undo_pci_write_data->dev = pci_get_dev(pacc, \
+ a->domain, a->bus, a->dev, a->func); \
+ else \
+ undo_pci_write_data->dev = NULL; \
undo_pci_write_data->reg = b; \
undo_pci_write_data->type = pci_write_type_##c; \
undo_pci_write_data->c##data = pci_read_##c(dev, reg); \