[PATCH] setupapi: Avoid race conditions with devnode_table.
Brendan Shanks
bshanks at codeweavers.com
Tue Feb 8 13:33:03 CST 2022
Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---
Fixes a crash where two threads calling SetupDiGetClassDevs() would end
up in alloc_devnode() at the same time. One thread would start iterating
through the table after devnode_table_size was set but before
devnode_table was allocated, and crash.
dlls/setupapi/devinst.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index ecc0b58ca5c..f3ae4fdb1da 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -233,11 +233,21 @@ static inline void copy_device_iface_data(SP_DEVICE_INTERFACE_DATA *data,
static struct device **devnode_table;
static unsigned int devnode_table_size;
+static CRITICAL_SECTION devnode_table_cs;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &devnode_table_cs,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": devnode_table_cs") }
+};
+static CRITICAL_SECTION devnode_table_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
static DEVINST alloc_devnode(struct device *device)
{
unsigned int i;
+ EnterCriticalSection(&devnode_table_cs);
+
for (i = 0; i < devnode_table_size; ++i)
{
if (!devnode_table[i])
@@ -260,21 +270,33 @@ static DEVINST alloc_devnode(struct device *device)
}
devnode_table[i] = device;
+
+ LeaveCriticalSection(&devnode_table_cs);
+
return i;
}
static void free_devnode(DEVINST devnode)
{
+ EnterCriticalSection(&devnode_table_cs);
devnode_table[devnode] = NULL;
+ LeaveCriticalSection(&devnode_table_cs);
}
static struct device *get_devnode_device(DEVINST devnode)
{
+ struct device *device = NULL;
+
+ EnterCriticalSection(&devnode_table_cs);
+
if (devnode < devnode_table_size)
- return devnode_table[devnode];
+ device = devnode_table[devnode];
+ else
+ WARN("device node %u not found\n", devnode);
- WARN("device node %u not found\n", devnode);
- return NULL;
+ LeaveCriticalSection(&devnode_table_cs);
+
+ return device;
}
static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
--
2.32.0 (Apple Git-132)
More information about the wine-devel
mailing list