Skip to content

Commit

Permalink
wcmUSB: Correct bounds check of maximum button number
Browse files Browse the repository at this point in the history
Automated test runs have detected the following issue while running UBSan
checks:

~~~
../src/wcmUSB.c:1372:11: runtime error: left shift of 1 by 31 places cannot
 be represented in type 'int'
    #0 0x7f0444bcbd8c in mod_buttons ../src/wcmUSB.c:1372
    #1 0x7f0444bd7f26 in test_mod_buttons ../src/wcmUSB.c:2090
    #2 0x7f0444bfcea7 in wcm_run_tests ../test/wacom-test-suite.c:46
    #3 0x56204d77b405 in main ../test/wacom-tests.c:44
    #4 0x7f0448625082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
    #5 0x56204d77b1cd in _start (/home/runner/work/xf86-input-wacom/xf86-input-wacom/builddir/wacom-tests+0x11cd)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../src/wcmUSB.c:1372:11 in

~~~

While the faulty line has some protection against an excessively-large
value of 'btn', the bounds are incorrect. A button number of 32 would
be allowed by the existing check but would also lead to undefined
behavior.

This commit modifies the bounds to properly fit the condition.

Link: https://github.com/linuxwacom/xf86-input-wacom/actions/runs/7049012015/job/19186502078
Signed-off-by: Jason Gerecke <[email protected]>
  • Loading branch information
jigpu authored and whot committed Nov 30, 2023
1 parent dbb8ddc commit bf61b3e
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/wcmUSB.c
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ mod_buttons(WacomCommonPtr common, unsigned int buttons, unsigned int btn, Bool
{
unsigned int mask;

if (btn >= sizeof(int) * 8)
if (btn >= sizeof(int) * 8 - 1)
{
wcmLogCommonSafe(common, W_ERROR,
"%s: Invalid button number %u. Insufficient storage\n",
Expand Down Expand Up @@ -2085,14 +2085,15 @@ static int usbProbeKeys(WacomDevicePtr priv)
TEST_CASE(test_mod_buttons)
{
WacomCommonRec common = {0};
for (size_t i = 0; i < sizeof(int) * 8; i++)
for (size_t i = 0; i < sizeof(int) * 8 - 1; i++)
{
unsigned int buttons = mod_buttons(&common, 0, i, 1);
assert(buttons == (1u << i));
buttons = mod_buttons(&common, 0, i, 0);
assert(buttons == 0);
}

assert(mod_buttons(&common, 0, sizeof(int) * 8 - 1, 1) == 0);
assert(mod_buttons(&common, 0, sizeof(int) * 8, 1) == 0);
}

Expand Down

0 comments on commit bf61b3e

Please sign in to comment.