mirror of
https://github.com/games-on-whales/wolf.git
synced 2026-10-15 13:02:03 +00:00
[PR #474] feat(input): fake-uinput shim for Steam Input in containers #489
Labels
No labels
🧠 1 - 🤖 999
AMD
bug
bug
cannot reproduce
documentation
duplicate
easy
enhancement
enhancement
enhancement
fixed?
fixed?
good first issue
hard
help wanted
Intel
invalid
LXC
medium
moonlight-protocol
Multi GPU
nixos
not a bug
nvidia
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/wolf#489
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/games-on-whales/wolf/pull/474
Author: @zerofltexx
Created: 8/9/2026
Status: 🔄 Open
Base:
beta← Head:feat/fake-uinput-steam-input📝 Commits (2)
d82c982feat(input): fake-uinput shim for Steam Input in containersa202377feat(api): serve the device endpoints on a restricted socket📊 Changes
20 files changed (+767 additions, -3 deletions)
View changed files
📝
85-wolf.rules(+10 -0)📝
CMakeLists.txt(+1 -0)📝
docker/startup.sh(+6 -0)📝
docker/wolf.Dockerfile(+10 -1)📝
docs/modules/ROOT/nav.adoc(+1 -0)➕
docs/modules/dev/pages/fake-uinput.adoc(+87 -0)➕
src/fake-uinput/CMakeLists.txt(+18 -0)➕
src/fake-uinput/fake-uinput.cpp(+207 -0)📝
src/moonlight-server/api/api.cpp(+27 -0)📝
src/moonlight-server/api/api.hpp(+34 -1)📝
src/moonlight-server/api/endpoints.cpp(+80 -0)➕
src/moonlight-server/api/fake_uinput.hpp(+122 -0)📝
src/moonlight-server/api/unix_socket_server.cpp(+34 -1)📝
src/moonlight-server/events/events.hpp(+6 -0)📝
src/moonlight-server/runners/docker.cpp(+20 -0)📝
src/moonlight-server/runners/docker.hpp(+9 -0)📝
src/moonlight-server/sessions/common.cpp(+32 -0)📝
src/moonlight-server/state/default/config.v7.toml(+4 -0)📝
tests/CMakeLists.txt(+1 -0)➕
tests/testFakeUinput.cpp(+58 -0)📄 Description
Implements #81, picking up from #88.
How it works
An app opts in with
WOLF_FAKE_UINPUT=1in its runner env. The default config ships that line commented out, since an opted in container gets the real/dev/uinput.For an opted in app Wolf preloads a shim (
src/fake-uinput) that interceptsioctl(UI_DEV_CREATE / UI_DEV_DESTROY)and posts the device toPOST /api/v1/runtime/{plug,unplug}-udev-device. Wolf reads it back from sysfs and does themknodplus fake-udev over its existingPlugDeviceEventpath, so the container never needsCAP_MKNOD. Only devices this session's shim created reach this session's container.An env var rather than a config field so it survives the round trip through wolf-ui lobbies, like
GOW_REQUIRED_DEVICESandRUN_SWAY. Docs indocs/modules/dev/pages/fake-uinput.adoc.Isolation
Devices the shim creates land on the host kernel, where logind would ACL them to the desktop user. The name rules in
85-wolf.rulescan't catch them because the app picks the name, and Steam Input calls its padMicrosoft X-Box 360 pad. Renaming breaks SDL, which maps controllers by name. So the shim stampsphyswithwolf-fake-uinput/0before theUI_DEV_CREATEit already intercepts, and the rules match on that to park the device onseat9and strip the ACL.This narrows the exposure without closing it. The container holds the real
/dev/uinputand could create a device by another route, carrying no marker.Testing
wolftestspasses on both compilers withBUILD_SHARED_LIBSon and off, including aarch64. New coverage intests/testFakeUinput.cpp.scripts/wolf-input-diag.shreports a shim created pad as reachable by the desktop user without the rule and root only with it. Ran a session with Steam Input on, gyro and per game bindings work, and the streamed pad doesn't reach the host desktop.The shim is x86 only, since Steam needs a 32 bit build of it and that uses
-m32.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.