Skip to content

Commit 190adeb

Browse files
committed
usb1: Make libusb_device_p a c_void_p.
Fixes a pypy3 segfault in USBDevice's finalizer with examples/hotplug.py . The pointers in the device_p array obtained from libusb_get_device_list are visibly not copied to the ctypes objects created while iterating the list. Once the list is freed by libusb_free_device_list, those ctypes pointers objects are reading the memory address from a freed memory location. With c_void_p, the iteration produces regular python integers, which forces the interpreter to get its own copy, which then survives list free. Unfortunately, this removes a ctypes typecheck on every function taking a libusb_device_p parameter.
1 parent 754c0bc commit 190adeb

2 files changed

Lines changed: 5 additions & 9 deletions

File tree

usb1/__init__.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,14 +2255,9 @@ def getDeviceIterator(self, skip_on_error=False):
22552255
try:
22562256
for device_p in device_p_p[:device_list_len]:
22572257
try:
2258-
# Instanciate our own libusb_device_p object so we can free
2259-
# libusb-provided device list. Is this a bug in ctypes that
2260-
# it doesn't copy pointer value (=pointed memory address) ?
2261-
# At least, it's not so convenient and forces using such
2262-
# weird code.
22632258
device = USBDevice(
22642259
context=self,
2265-
device_p=libusb_device_p(device_p.contents),
2260+
device_p=device_p,
22662261
registerFinalizer=self.__registerFinalizer,
22672262
unregisterFinalizer=self.__unregisterFinalizer,
22682263
can_load_configuration=True,

usb1/_libusb1.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,10 @@ class libusb_control_setup(Structure):
971971
# 1, and libusb_free_device_list() can optionally decrease the reference count
972972
# on all devices in the list. libusb_open() adds another reference which is
973973
# later destroyed by libusb_close().
974-
class libusb_device(Structure):
975-
pass
976-
libusb_device_p = POINTER(libusb_device)
974+
#class libusb_device(Structure):
975+
# pass
976+
#libusb_device_p = POINTER(libusb_device)
977+
libusb_device_p = c_void_p # Any pointer is fine
977978
libusb_device_p_p = POINTER(libusb_device_p)
978979
libusb_device_p_p_p = POINTER(libusb_device_p_p)
979980

0 commit comments

Comments
 (0)