Skip to content

Conversation

kodemeister
Copy link
Contributor

Description

This PR allows access to Sunshine's virtual keyboard, mouse, touchscreen and gamepad without adding the user to input group. This should simplify Sunshine setup for Linux users.

The trick is to add TAG+="uaccess" to Sunshine udev rule. It basically sets up proper ACL permissions on /dev/uinput for currently logged-in user. This is the modern way of granting device access to unprivileged users, rather than adding them to static groups. I removed the code that adds the user to input group from Linux packaging scripts and docs.

Note that uaccess tag only grants access to properly logged/authenticated users. For instance, users that were created in Docker containers should still be added to input group.

Screenshot

Issues Fixed or Closed

  • Closes #1086

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Branch Updates

LizardByte requires that branches be up-to-date before merging. This means that after any PR is merged, this branch
must be updated before it can be merged. You must also
Allow edits from maintainers.

  • I want maintainers to keep my branch updated

@CLAassistant
Copy link

CLAassistant commented Apr 3, 2023

CLA assistant check
All committers have signed the CLA.

@cgutman cgutman force-pushed the grant-access-to-input-devices branch from 55477b0 to d1a235f Compare April 7, 2023 04:40
if ! grep -q $GROUP_INPUT /etc/group; then
echo "Creating group $GROUP_INPUT"

groupadd $GROUP_INPUT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this broke the Docker builds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. I removed creation of input group from DEB/RPM postinstall script since udev rule makes it unnecessary. However, Docker images still try to create a lizard user and add it to input group:

useradd -lm -d ${HOME} -s /bin/bash -g "${PGID}" -G input -u "${PUID}" "${UNAME}"

Unfortunately, Debian/Ubuntu images don't have input group by default. That's why the build fails.

In this case I suggest to create lizard user without input group. Normally, users created in Docker containers don't have access to host devices. But as I see, UID and GID of lizard user are set to match UID and GID of host user. This means that if we properly install udev rule on the host, both host user and lizard user should be able to access Sunshine virtual devices. No input group needed.

Applied the changes in the commit below.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ABeltramo does this seem like a sane approach to you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a tricky one and would have to be tested, but if the udev rules are going to give group access to the specified GID and that's the same group mapped to the container, it should work.
Am I getting the approach here right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ABeltramo Basically yes, except that udev rules are going to give user access to the specified UID and that's the same user mapped to the container. Groups are not involved at all. The whole point of this PR is to avoid group permissions and rely on user permissions exclusively. It is intended to work in the following way:

  1. We install udev rule on the host.
  2. udev rule sets up ACL on /dev/uinput to grant R/W access to user on the host. Here is how permissions look on my system:
$ getfacl /dev/uinput
getfacl: Removing leading '/' from absolute path names
# file: dev/uinput
# owner: root
# group: input
user::rw-
user:kodemeister:rw-
group::rw-
mask::rw-
other::---

Please note the line user:kodemeister:rw-. This means that user kodemeister has R/W access to /dev/uinput in addition to standard Unix user/group/other permissions.
3. We run Docker container and mount /dev directory from host to container (-v /dev:/dev).
4. We create a new lizard user in the container and assign it the same UID as kodemeister user on the host.
5. As a result, lizard user should have access to /dev/uinput without messing with group permissions.

Indeed, this needs to be tested. Are there any instructions on running dockerized Sunshine? Setting up GUI apps in a container is a bit of pain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, makes perfect sense to me.
I'm on my phone, but I'll try just to add a couple of random notes:

  • There's no need to pass the full /dev to the docker container you can add: -v /dev/input:/dev/input:rw and --device /dev/uinput and that should be enough
  • As for running Sunshine in Docker I'm the main mantainer of Games on Whales https://github.com/games-on-whales/gow where we build a little image on top of Sunshine (coincidentally it's mainly just to setup additional user/group access) and a bunch of others so that you can "easily" run this in Docker.

@cgutman
Copy link
Collaborator

cgutman commented Apr 7, 2023

The general approach looks good to me. It seems to match what Steam is doing.

KERNEL=="uinput", SUBSYSTEM=="misc", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput", TAG+="uaccess"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the input devices group and mode redundant then and can be left unchanged?

Suggested change
KERNEL=="uinput", SUBSYSTEM=="misc", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput", TAG+="uaccess"
KERNEL=="uinput", SUBSYSTEM=="misc", OPTIONS+="static_node=uinput", TAG+="uaccess"

Or do you want to keep it for mentioned cases with users created in containers where it may still be needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the original intention was to keep group and mode for special cases, such as users created in Docker containers. Regular Linux users don't need group/mode configuration. TAG+="uaccess" already handles that.

But as discussed above, Sunshine container also doesn't seem to need additional group/mode configuration because it passes UID of host user to container. So GROUP="input", MODE="0660" seem redundant in this particular case as well.

Should I remove group/mode from udev rule and fully rely on TAG+="uaccess"? This is basically exactly what Steam did:

https://github.com/ValveSoftware/steam-devices/blob/master/60-steam-input.rules#L5

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove group/mode from udev rule and fully rely on TAG+="uaccess"? This is basically exactly what Steam did:

Seems reasonable to not override distro and possibly admin decisions about these UNIX permissions if Sunshine is not commonly make us of them anymore. However, let Sunshine maintainers comment on this first, as I would understand the argument to leave it in place for another testing/feedback iteration.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any negative effects leaving GROUP="input", MODE="0660" there?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily. But distributors and admins will be thankful when the changes to the system are limited to what is really needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess let's remove it then and we can put it back if we find issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I can think of only one negative effect. If a distro doesn't provide input group, udev might complain about it in system logs. Popular distros seem to have input group but it's better not to rely on it.

@cgutman cgutman force-pushed the grant-access-to-input-devices branch from 0cad101 to ca02d2d Compare May 6, 2023 17:24
@cgutman cgutman merged commit 343f200 into LizardByte:nightly May 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants