1967 Commits

Author SHA1 Message Date
Sean McBride
7719ae5632 io: Change remove_from_flying_list() to not lock flying_transfers_lock itself
This is now symmetric with add_to_flying_list(), which was already
requiring that *callers* lock flying_transfers_lock. Updated the only
2 callers.

This also makes the code correspond better to the big comment about
locking made in 138b661f.

Also documented at the top of several functions when they require that
flying_transfers_lock already be held. Verified by code review that it's
actually the case.

This should not change any behaviour at all.

References #1410
2024-01-19 20:28:48 +01:00
Tormod Volden
f9ae36b13f windows: Downgrade get_guid DeviceInterfaceGUID warning to info
Closes #1394

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2024-01-19 20:16:03 +01:00
Sean McBride
7b53ee1d73 libusb.h: Rename ZERO_SIZED_ARRAY to LIBUSB_FLEXIBLE_ARRAY
This reflects the C99 terminology, instead of the old hack of using a
zero sized array.

Also adds the LIBUSB prefix to avoid namespace colisions, as this is
present in a public header.

References #1409
2024-01-19 19:51:45 +01:00
Sean McBride
7ab9c93d7d core: Add missing mutex acquisition when manipulating active_contexts_list
The `active_contexts_list` is supposed to be protected by the
`active_contexts_lock` mutex.

Upon code review, found one place where the mutex was not acquired.

Closes #1413
2024-01-19 19:43:24 +01:00
Tormod Volden
a8fba21b7f Change libusb_init_option to fix libusb_set_option() on big-endian
libusb_set_option() is a variadic function, so the type of the arguments
is not clearly defined. When called with LIBUSB_OPTION_LOG_LEVEL, the
argument is read with va_arg() as an int, which matches the type used
when passing constants, and also most of the internal calls and the
calls in the examples.

However the internal call site in libusb_init_context() passes the ival
element of the libusb_init_option struct directly, which is of type
int64_t. This breaks on big-endian architectures like PowerPC, as
detected by tests/set_option.

Therefore change the libusb_init_option struct to use int here as well.

Thanks to Aurelien Jarno for reporting and initial patch.

Closes #1416
Closes #1436

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2024-01-19 19:39:26 +01:00
Sean McBride
56d8f3c558 io: Fix incorrect alignment in allocation in libusb_alloc_transfer
After being suspicous of some code I was browsing, I tried changing
PTR_ALIGN to align to 4096 bytes instead of just to pointer size (8
bytes), then enabled ASan then ran the xusb example, and it crashed.
What ensued was a big code review of that function and related code.

- reviewed use of macros like USBI_TRANSFER_TO_LIBUSB_TRANSFER

- introduced new macros TRANSFER_PRIV_TO_USBI_TRANSFER and
USBI_TRANSFER_TO_TRANSFER_PRIV to do pointer offset conversions

- introduced some temporary variables, especially for
USBI_TRANSFER_TO_LIBUSB_TRANSFER results

- move some variable assignment and declaration together

- replaced a few uses of PTR_ALIGN to instead use the alignment macros

In particular, libusb_alloc_transfer() was not using PTR_ALIGN()
on struct usbi_transfer and could allocate a wrong size.

Closes #1418
2024-01-19 19:37:17 +01:00
Sean McBride
20fb7513bc descriptor: Prevent string descriptor buffer overread
Calculate the correct size of both the source and destination buffers,
then determine which is shorter, and iterate only that many times.

The original code would read one byte beyond the descriptor buffer
if a device returned a broken string descriptor of byte length 255.

Closes #1432
2024-01-19 18:57:33 +01:00
Sean McBride
a91657aba0 darwin: Avoid error checking regression
Commit 13a69533 slightly/subtly made an incorrect change to error
checking. Before that commit, we had

  if (kIOReturnSuccess != kresult || !plugInInterface) {
    return NULL;
  }

which was correct. The commit changed the function signature. Instead of
returning the pointer directly, it now returns an error code directly,
and the pointer by reference.  The above block became:

  if (kIOReturnSuccess != kresult || !plugInInterface) {
    return darwin_to_libusb(kresult);
  }

But if kresult is somehow kIOReturnSuccess but plugInInterface is NULL
(probably impossible), then we'd return LIBUSB_SUCCESS but a NULL
pointer, which is a nonsense combination.

Closes #1430
2024-01-19 18:18:05 +01:00
Sean McBride
9401e6c7d9 darwin: Revert seemingly harmless introduction of temporary variable
Commit 13a69533 introduced a temporary variable for the device structure
(that originally was meant to be reverted, it turns out).

Here is a follow-up to revert this part, to avoid threading issues and
reported crashes.

The temporary variable would be harmless if there was no multithreading
happening, but there is:

On the hotplug background thread, darwin_devices_detached() is called,
which in turn calls Release() on the device, which frees the memory, and
then sets old_device->device to NULL. Shortly after,
darwin_devices_attached() is called (because the kernel driver is
reattaching?) and this calls darwin_get_cached_device(), which sets
->device to something new (and not NULL).

Meanwhile, back on the main thread, darwin_reenumerate_device() is
running and had cached ->device in the seemingly harmless temporary
variable. But that thing was already deallocated on the other thread!

Re-reading it from the structure makes it more likely you get the value
you want.

There might still be unfixed multithreading issues here, but this at least
avoids an obvious regression.

Fixes #1386
Closes #1427
2024-01-19 10:59:03 +01:00
Sean McBride
5ad1d992f1 core: Fix -Wswitch warnings by including all enum values in switch
No change in behaviour.

References #1426
2024-01-05 00:14:49 +01:00
Tormod Volden
31dfa14748 ChangeLog updates
Thanks to Lars Kanis and Sean McBride for noticing errors and
omissions.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2024-01-04 18:04:52 +01:00
Ingvar Stepanyan
37dee8f9dd msvc: Add tests/init_context project to MSVC 2023-12-19 01:02:41 +01:00
Tormod Volden
7c3d9ec61c tests/stress_mt: Ignore device descriptor mismatch for Windows HID
Some device descriptor fields are hard-coded by the HID backend, so they
will often not match. It is complicated to narrow this down to HID
devices, so we simply ignore these fields on Windows wholesale.

Hopefully we will fix the HID backend later, and this workaround can
then be reverted.

References #1360
References #1378

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-19 00:59:34 +01:00
Tormod Volden
5f9abfbe27 tests/stress_mt: Ignore some unavailable devices on Windows
Depending on the devices or drivers, open() may return
 LIBUSB_ERROR_ACCESS
 LIBUSB_ERROR_NOT_FOUND
 LIBUSB_ERROR_NOT_SUPPORTED
for devices "out of reach" to libusb.

References #1360

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-19 00:58:07 +01:00
Ingvar Stepanyan
c2e150773e tests/set_option: Allow no devices in test_no_discovery
Instead of assuming there will always be some devices detected (when not
using LIBUSB_OPTION_NO_DEVICE_DISCOVERY), let the test pass but print a
warning to the user if there is none. This is to allow automated build
tests on restricted build environments without USB devices.

References #1374
Closes #1379
2023-12-19 00:38:11 +01:00
Tormod Volden
b27247063b libusb.h: Avoid UNREFERENCED_PARAMETER macro on GCC/clang
The UNREFERENCED_PARAMETER macro is provided by MinGW headers but
interferes with -Wuninitialized on recent clang. So instead fall back to
the same UNUSED macro already used elsewhere with GCC.

Relevant discussion:
https://discourse.llvm.org/t/rfc-winnt-hs-unreferenced-parameter-vs-clangs-wunused-value/38526

Fixes #1381
Closes #1382

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-19 00:22:55 +01:00
Ingvar Stepanyan
87d6686a54 tests/stress_mt: Stop early if any device fails
Previously the loop would continue even if error has already occured
since `goto close` alone doesn't stop early.

References #1360
2023-12-12 16:59:42 +01:00
Aurelien Jarno
ebfbf195d4 tests/set_option: Avoid use-after-free in case of test failure
In case num_devices equals 0, LIBUSB_EXPECT() calls
LIBUSB_TEST_CLEAN_EXIT(), which calls libusb_exit() on test_ctx which
has just been freed a few lines above by a call to libusb_exit(). This
might cause a SEGFAULT or SIGBUS depending on the system.

Fixes that by assigning NULL to test_ctx just after calling
libusb_exit() like it is done elsewhere in the file.

Closes #1374
2023-12-11 23:26:09 +01:00
Tormod Volden
cc3df77609 libusb 1.0.27-rc1
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-10 17:33:32 +01:00
Tormod Volden
52bb0ede72 tests: Use AM_LDFLAGS for -static flag to allow LDFLAGS override
Fixes the following warning from automake:

tests/Makefile.am:3: warning: 'LDFLAGS' is a user variable, you should not override it;
tests/Makefile.am:3: use 'AM_LDFLAGS' instead

Also, since stress_mt_LDFLAGS is set (even in a conditional), AM_LDFLAGS
will not be applied for stress_mt unless added explicitly.

Closes #1371

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-10 17:29:13 +01:00
Tormod Volden
43db4d97d7 .gitignore: Ignore test binaries and logs
Closes #1370

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-09 10:38:56 +01:00
Tormod Volden
56cee16efd tests/umockdev: Avoid unknown warning option on older gcc
According to https://gcc.gnu.org/wiki/StaticAnalyzer the
-Wanalyzer-malloc-leak and -Wanalyzer-file-leak options came in GCC 10.

When building with GCC 9 there would be warnings:

CC       umockdev-umockdev.o
../../libusb-git/tests/umockdev.c:37:32: error: unknown option after ‘#pragma GCC diagnostic’ kind [-Werror=pragmas]
   37 | #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
      |                                ^~~~~~~~~~~~~~~~~~~~~~~~
../../libusb-git/tests/umockdev.c:38:32: error: unknown option after ‘#pragma GCC diagnostic’ kind [-Werror=pragmas]
   38 | #pragma GCC diagnostic ignored "-Wanalyzer-file-leak"
      |                                ^~~~~~~~~~~~~~~~~~~~~~

Closes #1369

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-09 09:06:41 +01:00
Martin Ling
dac541dc75 Revert "windows: Add option for WinUSB RAW_IO endpoint policy"
This reverts commit 9e4bb9cbe5.

References: #1297
2023-12-09 09:06:32 +01:00
Ingvar Stepanyan
066a77fc0b webusb: Wasm+WebUSB backend fixes and improvements
- Added long-awaited support for multithreading. Since WebUSB still
 doesn't support accessing same device from multiple threads, this works
 by proxying I/O operations to the main thread as discussed on the
 original issue. For applications that run on the main thread nothing
 changes and they will continue to access WebUSB via Asyncify like
 before, while other threads will use blocking mechanism until an
 asynchronous response is available from the main thread.

 - Rewrote notification mechanism to use atomic waiting via sync Wasm
 instructions or `Atomics.waitAsync` depending on the thread. This
 results in simpler and faster notifications than the previous
 `postMessage`-based approach (which was used because
 `Atomics.waitAsync` wasn't yet available), as well as allows to send
 notifications across threads for multithreading scenario described
 above.

 - Fixed notification access to only wait/notify on the event we're
 interested instead of using a global lock.

 - Rewrote descriptor reading to query device for raw device &
 configuration descriptors instead of re-serializing them from
 JavaScript object representation. This incurs slight extra cost for the
 initial device opening, but fixes number of issues with information
 that is not yet exposed via WebUSB and allows to read supplementary
 descriptors such as string and BOS which were previously not supported.

 - Fixed listing only one alternate instead of all the available ones.

 - Fixed device closing & re-opening which could previously error out
 with "device busy" error.

 - Added mandatory Emscripten-specific linking flags to the generated
 pkgconfig.

 - Added device speed inference. This is not yet exposed via WebUSB, but
 we can at least make a best effort guess based on USB version and
 packet size, like some other backends already do.

 - Simplified & fixed device session ID generation which is now
 guaranteed to be truly unique, whereas previously it could clash with
 other devices of the same type.

 - Prepare code to support building for the Web without mandatory
 multithreading (which is costly on the Web) in the future. For now
 those `#ifdef`s are defunct as libusb is always compiled with
 `-pthread`, but some upcoming changes on the Emscripten side will allow
 to leverage those codepaths for smaller Wasm binaries.

 - Require explicit `--host=wasm32-unknown-emscripten` as we might want
 to add non-Emscripten WebAssembly backends in the future.

 - Various smaller fixes and improvements.

Note that this requires Emscripten 3.1.48 or newer to build for some of
the features used here, namely `co_await` support for JavaScript values
(without it code would be both more complex and slower) and some
proxying APIs. It shouldn't be a big deal in practice as most users
retrieve Emscripten via the official emsdk installer or Docker images.

Closes #1339
2023-12-08 22:17:40 +01:00
Nathan Hjelm
1ca2bc14ce darwin: add testing for IOKit version fallbacks
This commit adds a new unit test that verifies that the interface
interface and device interface versions are as expected. The unit test
relies on new testonly symbols to get details about the implementation.
The commit also adds a sanity check on the versions to ensure that
libusb_init fails if a supported version can not be found.

In addition to the new tests this commit also updates the tests to
use the static version of libusb. This provides them access to any
hidden symbol including testonly symbols (which should never be
exported in the shared library).

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-07 12:54:03 -07:00
Nathan Hjelm
13a6953379 darwin: add abstraction for IOUSBDeviceInterface
The IOUSBDeviceInterface object is used by libusb to interact with USB
devices macOS (Darwin, MacOS X, iOS, etc). For as long as libusb has
existed it has always used the highest available version (at compile
time) of this interface. This change breaks that by using the higest
version available between the compile environment and the version of
macOS running at execution time. This allows the same libusb build to
run on older and newer versions of macOS without disabling newer
features.

This change relies heavily on the fact that each new version of the
IOUSBDeviceInterface object builds on prior versions. This means that
libusb can use the oldest version of the interface that has a specific
function without needing to use the specific version specified at open
time which greatly simplifies the code.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-07 12:54:03 -07:00
Nathan Hjelm
cf6946dc48 darwin: add abstraction for IOUSBInterfaceInterface
The IOUSBInterfaceInterface object is how libusb interfaces with the
interfaces of USB devices on macOS (Darwin, MacOS X, iOS, etc). For as
long as libusb has existed it has always used the highest available
version of the interface. This change breaks that by using the higest
version available for the current running version of macOS. This allows
the same libusb build to run on older and newer versions of macOS
without disabling newer features.

This change relies heavily on the fact that each new version of the
IOUSBInterfaceInterface object builds on prior versions. This means that
libusb can use the oldest version of the interface that has a specific
function without needing to use the specific version specified at open
time which greatly simplifies the code.

This commit update IOUSBInterfaceInterface only and leave the
IOUSBDeviceInterface as-is. A follow-on change will update the device
interface.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-07 12:54:03 -07:00
Nathan Hjelm
33e92b6c49 darwin: add get_running_version helper
This helper returns an integer representation of the currently running
OS from 100000 (10.0) on. This allows the Darwin backend to make
decisions base on the running version without using the
__builtin_available() feature. This builtin is only available in Clang
and not gcc. For newer versions of macOS the helper uses the
kern.osproductversion sysctl and falls back to kern.osrelease and a
mapping of Darwin -> OS X/macOS versions.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-07 12:54:03 -07:00
Nathan Hjelm
43c6fe0b59 ci: ensure testsuite log is dumped on failure
Move make check into the if conditional to ensure that the failure does
not force the script to immediately exit.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-06 12:45:43 -07:00
Nathan Hjelm
f0d1ff3fb6 ci: dump test suite output on test failure
The test output is hidden by default with make check so we need to explicitly
dump the test suite log on failure.

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-05 11:08:33 -07:00
Nathan Hjelm
d82b3d27b1 ci: do not hard code test names for CI
automake has built-in support for running unit test with make check. This commit
sets the TESTS variable in tests/Makefile.am to enable this support and updates
the CI script to use make check instead of hard-coded test names.

Closes #1361

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
2023-12-05 10:58:15 -07:00
Tormod Volden
30a44345b4 CI: Add Linux and MSYS build with logging disabled
Closes #1357

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-03 11:43:20 +01:00
Tormod Volden
a8f77014a1 CI: Simplify Linux job description
Omit specifying bash shell, which is default on Linux (and macOS)
anyway, also since we are not using any particular shell features.

This makes it all consistent with the mockdev step.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-03 11:42:35 +01:00
Tormod Volden
f2ebac604d windows: Include enumeration details in debug output
It doesn't add much extra noise and helps a lot to interpret
the existing debug output.

Change the wording slightly from the previous commented-out
debug output. Grep for "ENUM" to find these in the logs.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-01 11:02:29 +01:00
Tormod Volden
5eed745ee0 windows: Avoid warning with logging disabled
Fixup of commit fdab67b1

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-01 11:00:58 +01:00
Tormod Volden
80493dddfc core: Avoid warning with logging disabled
Fixup of commit 9de0fefb

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-01 11:00:29 +01:00
Tormod Volden
ae3685e038 stress_mt: Return error if device count varies
And otherwise only print the device count once,
together with the number of devices not opened.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-12-01 10:56:00 +01:00
Ingvar Stepanyan
a8d3cd8031 tests/stress_mt: Test open/transfer/close on available devices
Verify that you can open a device, do some transfer (a device descriptor
control transfer was chosen as it should succeed with any connected
device), and close a device from multiple threads in parallel as well.

Print a warning if a device is readonly.

Consistently add thread flags to the build.

Closes #1347
2023-12-01 10:55:36 +01:00
Ingvar Stepanyan
bd91a0c145 CI: Enable Emscripten build
Closes #1351
2023-11-30 11:54:27 +01:00
Ingvar Stepanyan
fd315026f4 Add WebUSB testing via node-usb 2023-11-30 11:52:26 +01:00
SomeAlphabetGuy
9de0fefb31 core: Avoid possible data race in log_v()
The logging function usbi_dbg() called from udev event thread needs to
safely get the log level of the default context or the fallback context.
This is not trivial because udev thread may log events while contexts
are created and destroyed. Locking the default context mutex is not an
option because usbi_dbg() may be called from code that already holds
this mutex, which would lead to a deadlock. The solution implemented in
this commit is to maintain a separate atomic global variable with the
default debug level.

The issue was found with ThreadSanitizer, although no actual bugs have
been observed.

libusb_set_debug() was also changed to call libusb_set_option() instead
of doing its own option setting which had fewer checks.

Closes #1332
2023-11-30 11:36:27 +01:00
Ingvar Stepanyan
dfed0d1695 CI: Pass the extra warnings flags to CXXFLAGS too
In particular upcoming emscripten builds will make use of this.
2023-11-29 23:21:22 +01:00
Ingvar Stepanyan
143338c342 CI: Tell tests that we don't have any devices
The test_no_discovery test would otherwise expect to find some devices
when running without NO_DEVICE_DISCOVERY.
2023-11-29 18:55:48 +01:00
Ingvar Stepanyan
c0057c3942 CI: Enable Address Sanitizer (ASAN) where supported
GCC on MSYS2 doesn't have ASAN support.

And do not enable it for MSVC "Release" target.
2023-11-29 18:54:24 +01:00
Ingvar Stepanyan
e28fa3069a CI: Run cross-platform tests on all platforms
Except Linux netlink and msys2-clang32 where they don't work.
2023-11-29 18:53:37 +01:00
Ingvar Stepanyan
5fa085efb7 testlib: Don't count skipped tests as failures 2023-11-29 18:53:19 +01:00
Ingvar Stepanyan
6d2abd0990 tests: Mark callbacks as LIBUSB_CALL
Fixes #1337
2023-11-29 18:11:50 +01:00
Tormod Volden
c4285dd49d windows: Cover all enumeration passes explicitly in switch statements
This is only for readability and doesn't change the behaviour.

Several passes were implicitly grouped together in the "default" case,
which made the code unnecessarily hard to read. The reason was that the
number of EXT passes is not known, so those were conveniently treated in
the "default" case together with some non-EXT passes.

Instead introduce a "pass_type" helper variable which has a defined
range, and add all pass types explicitly in the switch statements.

At the same time update the comment which shortly explains the different
passes, it hasn't reflected reality for a long while.

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-11-29 18:10:58 +01:00
Tormod Volden
d291eec441 Revert "core: Remove select case not possibly reached"
This reverts commit cd8078db, which although it made a static analyzer
happy, unfortunately got compilers to complain (with -Wswitch-enum
enabled).

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-11-29 18:10:43 +01:00
Tormod Volden
acc7b9d4de tests: Fix builds with logging disabled
set_option.c gave warnings and init_context.c would fail to build on
Windows.

Tested with configure options --disable-log and --enable-debug-log

Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
2023-11-29 18:10:16 +01:00