aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-09-15 15:04:01 +0100
committerMichael Brown <mcb30@ipxe.org>2022-09-15 15:20:58 +0100
commit56b30364c5db6367279ffe88929f286f15680b40 (patch)
tree0062a8909e99c573d3c421d7d73a8321bff289f0
parent8fc3c26eae8d45a5391a39ee698817449299bd76 (diff)
downloadipxe-56b30364c5db6367279ffe88929f286f15680b40.zip
ipxe-56b30364c5db6367279ffe88929f286f15680b40.tar.gz
ipxe-56b30364c5db6367279ffe88929f286f15680b40.tar.bz2
[pci] Check for wraparound in callers of pci_find_next()
The semantics of the bus:dev.fn parameter passed to pci_find_next() are "find the first existent PCI device at this address or higher", with the caller expected to increment the address between finding devices. This does not allow the parameter to distinguish between the two cases "start from address zero" and "wrapped after incrementing maximal possible address", which could therefore lead to an infinite loop in the degenerate case that a device with address ffff:ff:1f.7 really exists. Fix by checking for wraparound in the caller (which is already responsible for performing the increment). Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/bus/pci.c6
-rw-r--r--src/hci/commands/pci_cmd.c6
-rw-r--r--src/include/ipxe/errfile.h1
3 files changed, 10 insertions, 3 deletions
diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c
index 60d5df1..c5deb08 100644
--- a/src/drivers/bus/pci.c
+++ b/src/drivers/bus/pci.c
@@ -352,8 +352,7 @@ static int pcibus_probe ( struct root_device *rootdev ) {
uint32_t busdevfn = 0;
int rc;
- for ( busdevfn = 0 ; 1 ; busdevfn++ ) {
-
+ do {
/* Allocate struct pci_device */
if ( ! pci )
pci = malloc ( sizeof ( *pci ) );
@@ -386,7 +385,8 @@ static int pcibus_probe ( struct root_device *rootdev ) {
/* Not registered; re-use struct pci_device */
list_del ( &pci->dev.siblings );
}
- }
+
+ } while ( ++busdevfn );
free ( pci );
return 0;
diff --git a/src/hci/commands/pci_cmd.c b/src/hci/commands/pci_cmd.c
index 515798b..5bae66f 100644
--- a/src/hci/commands/pci_cmd.c
+++ b/src/hci/commands/pci_cmd.c
@@ -22,6 +22,7 @@
*/
#include <stdio.h>
+#include <errno.h>
#include <getopt.h>
#include <ipxe/pci.h>
#include <ipxe/command.h>
@@ -79,6 +80,10 @@ static int pciscan_exec ( int argc, char **argv ) {
} else {
/* Setting is defined: start searching from next location */
busdevfn = ( prev + 1 );
+ if ( ! busdevfn ) {
+ rc = -ENOENT;
+ goto err_end;
+ }
}
/* Find next existent PCI device */
@@ -101,6 +106,7 @@ static int pciscan_exec ( int argc, char **argv ) {
}
err_store:
+ err_end:
err_find_next:
err_parse_setting:
err_parse_options:
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 359e4d2..9b955e5 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -397,6 +397,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ERRFILE_linux_sysfs ( ERRFILE_OTHER | 0x00560000 )
#define ERRFILE_linux_acpi ( ERRFILE_OTHER | 0x00570000 )
#define ERRFILE_dynkeymap ( ERRFILE_OTHER | 0x00580000 )
+#define ERRFILE_pci_cmd ( ERRFILE_OTHER | 0x00590000 )
/** @} */