mirror of
https://github.com/joleuger/vuinputd.git
synced 2026-11-05 01:17:20 +00:00
[GH-ISSUE #1] [FEATURE} Add support for rootless containers by executing privileged tasks on the host #3
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
joleuger/vuinputd#3
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?
Originally created by @ShaneTRS on GitHub (Dec 23, 2025).
Original GitHub issue: https://github.com/joleuger/vuinputd/issues/1
Permission errors occur when
MKNODis attempted from within the container. I got around this error by dropping the --target-namespace arguments forAction::MknodDevice.I also ran into permission errors when trying to create files in
/run/udev/datafor some reason, but I assume that's a configuration issue on my end.I'm hoping I don't have a fundamental misunderstanding here, but it seems like it'll be possible to do this entirely unprivileged (outside of the daemon running with CAP_MKNOD and other relevant capabilities)
@joleuger commented on GitHub (Dec 27, 2025):
Thank you for trying out vuinputd. As it is in a prototype stage, any comments or issues or input is valuable.
The
--targetoption was designed to enter the mount namespace of a container process in cases where the container has its own private/dev/input, different from the host. In this mode,mknodis executed as root but inside the target namespace, so that the device node is created in the container’s/dev.Dropping
--targetis only correct if the daemon if the host and container share the same/dev/input, in which case nomknodis required at all because the device node is already present.If the host and container do not share
/dev/input, then entering the container’s namespace (via--target) is required formknodto have the intended effect, and the host namespace of vuinputd must haveCAP_MKNOD.(Edit: made the paragraph more technical precise)
This might have a lot of reasons. You can try to make sure that a writable /run is available in the container by creating a tmpfs there. Can you describe your detailed setup? Then, I'll try to write an integration test for that kind of setup and provide more detailed debugging messages. I haven't finished it yet, but I have documented my setup on https://github.com/joleuger/containerized-headless-sunshine-howto. Just one note for now: Actually calling
is important for libinput to read the udev messages. That is a known libinput quirk.
In the next days, I'll add some code that makes it easier to debug with strace.
@joleuger commented on GitHub (Dec 28, 2025):
have added some additional debugging support to the current HEAD.
Whenever mknod is supposed to be executed inside a container, vuinputd now emits additional debug output, for example:
If you run the suggested strace command, the output might look like this:
In this example, the output clearly shows that the container process no longer exists at the time vuinputd tries to enter its namespace.
This kind of output should make it easier to distinguish between:
@ShaneTRS commented on GitHub (Dec 29, 2025):
The added debug information was extremely helpful, thank you! I managed to get it working. Though I did have some more troubles with /run/data, I managed to find a workaround via
-v /tmp/stardust-run/$PORT:/run:rslave,rwI thought maybe it was a UID mapping problem, but even something like
--tmpfs /run:mode=777didn't workstrace.txt
@joleuger commented on GitHub (Dec 29, 2025):
Thank you for the detailed report and the
stracelogs. The investigation clearly shows that theEOVERFLOW(Value too large for defined data type) is caused by a User Namespace ID mapping mismatch.The Technical Cause (my current hypothesis)
When the tool enters the container’s Mount Namespace but remains in the Host’s User Namespace, it creates a "cross-namespace" conflict:
/runontmpfs) is owned by the Container's Root (e.g., Host UID 100000).EOVERFLOW.Proposed Solution: "Ownership Alignment"
To fix this without losing the
CAP_MKNODprivileges required for device creation, we need to align our filesystem identity with the container's expectations. I am considering two implementation paths:setfsuid/setfsgid(Surgical)We temporarily adopt the target filesystem's UID/GID for IO operations only. This is the traditional way systems tools (like NFS servers or
nsenter) handle this without dropping process capabilities.setresuid+SECBIT_KEEP_CAPS(Modern/Strict)A more modern approach that changes the Effective UID. This is more verbose as it requires managing
prctlsecurebits and manually restoring the effective capability set viacapset, but it avoids the "deprecated" feel ofsetfsuid.The Plan
I will proceed as follows:
EOVERFLOWin our CI pipeline.mkdirandmknodwithin the container's/runwithout requiring the host-volume workaround.Thanks again to @ShaneTRS for the excellent investigation!
@joleuger commented on GitHub (Jan 16, 2026):
I am doing some tests, I am just writing down some notes here:
-v /dev/input:/dev/input:rslave,rw, I need the flag--device-cgroup-rule="c 13:* rwm".Error: device cgroup rules are not supported in rootless mode or in a user namespace=>-v /dev/input:/dev/input:rslave,rwis currently requiredNext: more rootless tests
@joleuger commented on GitHub (Jan 20, 2026):
The original request should be complete. It is now possible to set vuinputd into a mode in which vuinputd does not try to get into the container and create the devices and udev files, but creates them on the host. Then, the user needs to bind-mount the directories on the host. See https://github.com/joleuger/vuinputd/blob/main/docs/USAGE.md
Some tests need to be completed, before I create a release with this new functionality. But an automatic integration test has been setup. Also, I am unsure if mknod the character device files into /run/vuinputd-folder is actually a good idea. Maybe bind-mounting them is better.