Skip to content

Out-of-bounds access in SetKey for virtual-key codes >= 128 #33

Description

@BillSkiCO

Summary

SetKey in src/cmdtab.c indexes the Keyboard array out of bounds for any virtual-key code ≥ 128.

Details

The array is declared as:

static u16 Keyboard[16]; // 256 bits to track key repeat for low-level keyboard hook

16 elements × 16 bits does total 256 bits, but the indexing in SetKey treats the array as bytes:

bool wasdown = Keyboard[key/CHAR_BIT] & (1 << (key % CHAR_BIT)); // getbit
Keyboard[key/CHAR_BIT] |= (1 << (key % CHAR_BIT));               // setbit1

With CHAR_BIT = 8, key/CHAR_BIT produces element indices 0–31, but the array only has elements 0–15. Any vkCode ≥ 128 reads and writes past the end of the array into adjacent static data.

This isn't an exotic case - it happens with ordinary keys:

  • VK_LSHIFT / VK_RSHIFT = 0xA0 / 0xA1 → index 20
  • VK_OEM_3 (backquote/tilde, the default window-cycle hotkey) = 0xC0 → index 24

So the default Alt-Backquote hotkey itself triggers the OOB write on every press. The writes are single-bit set/clear operations landing in whatever statics the linker placed after Keyboard (likely the Apps array), so the symptom would be subtle state corruption rather than a crash.

Additionally, key % CHAR_BIT only addresses bits 0–7 of each 16-bit element, so half of each u16 is never used - the effective capacity is 128 bits even though 256 were intended.

Suggested fix

Either declare the array as bytes to match the indexing:

static unsigned char Keyboard[32]; // 256 bits

or keep u16 and index in 16-bit granularity:

Keyboard[key/16] & (1 << (key % 16))

Environment

Found during a source review of tag v1.6.4 (dc42759). Present in the current main as well.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions