ValveSoftware / ValveSoftware/wine

Crash in xinput1_3 XInputGetState when SteamGameId environment variable isn't set

Open Beginner friendly
#353 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
2k
Forks
488
PR merge metrics
No merged PRs in 30d

Description

experimental_11.0 (experimental-11.0-20260903b) and bleeding edge. dlls/xinput1_3/main.c:863 (xinput1_4 merges this code):

ret = get_current_state(index, state) ? ERROR_SUCCESS : ERROR_DEVICE_NOT_CONNECTED;
if (ret == ERROR_SUCCESS) goto done;
sgi = getenv("SteamGameId");
if (!strcmp(sgi, "298110")) goto done;

The getenv result goes straight to strcmp without a NULL check. With SteamGameId unset, XInputGetState dereferences NULL and the process exits with EXCEPTION_ACCESS_VIOLATION reading address 0x0.

Seen with Subliminal (appid 2300840, UE 5.7.4) on experimental-11.0-20260903b. Crash log callstack:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000

ucrtbase.dll!strcmp()
XINPUT1_4.dll!0x180005f7d()
XINPUT1_4.dll!0x180020d0()
Subliminal-Win64-Shipping.exe

Disassembly at xinput1_4+0x5f60 confirms the sequence: load "SteamGameId", call getenv, load "298110" into rdx, pass the (NULL) getenv result in rcx, call strcmp:

lea    0x2f6d(%rip),%rcx   # 180008ed4 -> "SteamGameId"
call   *0x9623(%rip)       # getenv
lea    0x2f6c(%rip),%rdx   # 180008ee0 -> "298110"
mov    %rax,%rcx
call   *0x9643(%rip)       # strcmp

Repro: any game that calls XInputGetState, run through proton run with STEAM_COMPAT_CLIENT_INSTALL_PATH / STEAM_COMPAT_DATA_PATH set and SteamGameId not exported. Also reproduced with steam steam://rungameid/2300840, which apparently doesn't export it either. Normal Steam library launches set the variable and don't hit this. The hack is absent from proton_11.0, so stable releases are unaffected.

Every other getenv("SteamGameId") call site I checked (d3d8, d2d1, ddraw, gdiplus, ieframe, metahost, mshtml, quartz, rsaenh, wgl) is guarded; this is the only one without the check. Same class as #228, the identical missing NULL check in opengl32.

Patch:

sgi = getenv("SteamGameId");
if (sgi && !strcmp(sgi, "298110")) goto done;

Workaround until then: export SteamGameId= before launching.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at dlls/xinput1_3/main.c:863 in XInputGetState and inspect the SteamGameId lookup before strcmp. Reproduce with proton run while SteamGameId is unset, then verify the missing-variable path no longer crashes and that the existing SteamGameId behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
operating-systems
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
92/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.