2

Because of a long not-fixed bug in Steam with Linux, I want to block a specific program (Steam) from having any access whatsoever to a specific device (Sony DualShock 4 controller).

I tried setting some udev rules around a custom group and then running Steam as a custom user that is not in that group, but that avenue broke down when su couldn't do GUI stuff and pkexec had no doable (or secure) way to preserve really any environment variables, resulting in numerous problems including an immediate failure due to that custom user's /home directory not existing. Now I'm out of ideas.

2 Answers 2

1

I finally figured out that I can use a sandbox to accomplish this. Specifically firejail. I came up with a command that does nothing but block hidraw devices (which includes all Bluetooth controllers and is how Steam detects a Bluetooth DS4). The only controller I use through Bluetooth is my DS4, so that's a good enough solution for me:

firejail --noprofile --blacklist="/dev/hidraw*" /usr/bin/steam

It totally works! Steam can't see the DS4 and doesn't crash. However, certain games, like Shadow of Mordor, don't seem to like this method. Most games work fine, but SoM will see my DS4 (and even know it's a DS4, because it goes with PlayStation button prompts despite my tricking Steam into thinking it's specifically a 360 controller with sc-controller), and yet refuse to accept any input from it. I still have some work ahead of me.

EDIT: Success! After more testing, I figured out SoM's problem was that the game wasn't the best Linux port, and simply isn't compatible with anything DS4-related that isn't the DS4 itself. That is, trying to have it emulate something else with any userspace driver--xboxdrv, ds4drv, sc-controller, etc.--does not play nice with this game. So, I went and made a whole script for launching Steam, that goes and blocks my entire Bluetooth adapter instead of hidraw devices. Since this Steam bug is caused by PulseAudio configurations, I took a gamble and figured that if I just block Steam's access to the controller's entire USB device, but let Steam discover all of the bits and pieces of it besides, from hidraw to /dev/input/jsX, it would work. And it worked. Here are the relevant parts of my script:

#!/bin/bash
BLUETOOTH="$(lsusb | grep "8087:07dc")" # those are my BT adapter's device and vendor IDs; yours may be different
BUS="$(echo "$BLUETOOTH" | sed 's/.*Bus \([0-9]\+\).*/\1/')"
DEV="$(echo "$BLUETOOTH" | sed 's/.*Device \([0-9]\+\).*/\1/')"
BLACKLIST="/dev/bus/usb/$BUS/$DEV"

firejail --noprofile --blacklist="$BLACKLIST" /usr/bin/steam

(I took that gamble, rather than blocking anything sound-related from the controller, because though the controller does have a soundcard in it, and though that's probably why Steam has this issue at all, I can't find a way to access anything related to said soundcard over /sys or /dev.)

0

Okay, this answer is not quite matching the question because it asks for blocking access to specific programs. But in case nothing works, there is a very naïve and easy solution which is to disable read access to any device that causes problems with a program or game. After having used the program, turn device access back on.

This POSIX command disables read access to selected device files

sudo chmod a-r /dev/input/js*  # list device files with whitespace separation

No program will be able to get input from the device while reading is disabled.

And this command enables it again

sudo chmod a+r /dev/input/js*

Some application managers have pre-launch and post-exit scripts where this can be entered. But the solution is quite suboptimal. No other program will be able to read the device in between.

But firejail is definitely the better answer and should work on any major OS (except native Windows I guess).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .