mirror of
https://github.com/joleuger/vuinputd.git
synced 2026-07-17 16:36:03 +00:00
Add documentation and license information.
This commit is contained in:
parent
49149e2b48
commit
cb59fc73b5
10 changed files with 116 additions and 0 deletions
47
README.md
Normal file
47
README.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# vuinputd
|
||||
A minimal **CUSE-based proxy for `/dev/uinput`** that lets unmodified applications (like [Sunshine](https://github.com/LizardByte/Sunshine)) run inside a container while creating virtual input devices on the host.
|
||||
|
||||
## Overview
|
||||
|
||||
This project makes it possible to run [Sunshine](https://github.com/LizardByte/Sunshine) inside `systemd-nspawn` containers without breaking input isolation.
|
||||
|
||||
Normally, Sunshine creates virtual input devices via `/dev/uinput`. If `/dev/uinput` is simply bind-mounted into a container:
|
||||
|
||||
* Devices from one container can leak into another.
|
||||
* Keyboards and mice may attach to host seats that are attached to a running session.
|
||||
|
||||
This project solves that by introducing a **mediated input stack**:
|
||||
|
||||
* A **fake `/dev/uinput`** inside the container.
|
||||
* A daemon that **forward** add/remove events into the container, making SDL2 and Wayland/libinput behave correctly.
|
||||
* A **host proxy** that safely creates the real devices.
|
||||
* **udev rules** that tag and isolate devices per-container.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
* **Container**: Sunshine writes to fake `/dev/uinput`.
|
||||
* **Host Proxy**: Creates real devices on the host, labeled with container identity Forwards add/remove events into the container, so SDL2 and Wayland see devices natively.
|
||||
* **udev**: Matches by identity, prevents host use.
|
||||
|
||||
---
|
||||
|
||||
## Benefits
|
||||
|
||||
* 🎮 **SDL2 / Wayland compatibility**: fake-udev ensures compositors and games see device events properly.
|
||||
* 🔒 **Isolation**: containers only see their own devices; host also sees them, but ignores them completely.
|
||||
* ♻️ **Lifecycle safety**: devices are removed cleanly when Sunshine stops.
|
||||
* 🛠️ **Simple integration**: no kernel patches, just userspace tools + udev rules.
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
See [docs/DESIGN.md](docs/DESIGN.md) for detailed architecture, design tradeoffs, and security considerations.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
37
docs/DESIGN.md
Normal file
37
docs/DESIGN.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Design Document
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
This project provides a safe way to run [Sunshine](https://github.com/LizardByte/Sunshine) inside `systemd-nspawn` containers.
|
||||
Sunshine requires creating virtual input devices (`/dev/uinput`) for keyboards, mice, and controllers.
|
||||
|
||||
Naively exposing `/dev/uinput` from the host into a container breaks isolation: containers could create devices visible to other containers, and the host could even start consuming those devices.
|
||||
|
||||
---
|
||||
|
||||
## 2. Design Decisions
|
||||
|
||||
### 2.1 Where `/dev/uinput` lives
|
||||
|
||||
* **Decision**: Provide a fake `/dev/vuinput` backed by host proxy. This character device can be bind mounted inside containers to `/dev/uinput`.
|
||||
* **Why**: Prevents containers from creating devices visible system-wide.
|
||||
|
||||
### 2.2 Prevent host from using devices
|
||||
|
||||
* **Decision**: udev rules strip `ID_INPUT_KEYBOARD` and `ID_INPUT_MOUSE`, set `ID_SEAT=seat_vuinput`.
|
||||
* **Why**: Ensures devices are invisible to host input subsystems while still available in containers.
|
||||
|
||||
### 2.3 udev events in containers
|
||||
|
||||
* **Decision**: Proxy forwards udev events into the container via netlink.
|
||||
* **Why**: Without this, SDL2 and libinput might not recognize devices correctly; with it, containers behave as if devices were created locally.
|
||||
|
||||
### 2.4 Where to run the proxy
|
||||
|
||||
* **Decision**: Run proxy on host, one instance per container.
|
||||
* **Why**: Only host can safely access `/dev/uinput` and enforce mediation.
|
||||
|
||||
### 2.5 Security trade-off
|
||||
|
||||
* **Decision**: Accept that host always sees devices, but enforce rules to stop it consuming them.
|
||||
* **Why**: Full input namespaces don’t exist in Linux today; mediation is the practical compromise.
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::{collections::HashMap, future::Future, pin::Pin, time::Duration};
|
||||
|
||||
use async_io::Timer;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use nix::sys::stat::{makedev, mknod, stat, Mode, SFlag};
|
||||
use nix::unistd::{chown, Gid, Uid};
|
||||
use std::error::Error;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
pub mod inject_in_container_job;
|
||||
pub mod remove_from_container_job;
|
||||
pub mod mknod_input_device;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::mem;
|
||||
use std::os::fd::{AsRawFd, OwnedFd};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::{collections::HashMap, future::Future, pin::Pin, time::Duration};
|
||||
|
||||
use async_io::Timer;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Author: Johannes Leupolz <dev@leupolz.eu>
|
||||
|
||||
use async_channel::{Receiver, Sender};
|
||||
use futures::executor::{LocalPool, LocalSpawner};
|
||||
use futures::future::RemoteHandle;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue