Shared memory in /dev/shm rewriting

I’m attempting to snap a popular game/app which has been a devil. Unfortunately it makes heavy use of Shared Memory using /dev/shm files. I’ve attempted using the snapcraft-preload to automatically rewrite the paths but it seems that the nested style of execution that the app performs kills-off the environment where LD_PRELOAD is defined before the client starts. We really need a way for the shared memory file paths to be transparently re-named without both the applications knowing about it (makemkv seems to ignore that the filename changed and detects that the file wasn’t created where it wanted it and b0rks, for example) and that does not rely on LD_PRELOAD due to the ephemeral nature of environment variables and apps being able to unset when they execve a child process.

Thoughts?

1 Like

By Popular Game/app you mean steam right? Though i won’t be able to run :frowning: arch linux user

Our game also using shared memory for client-server communication on initialization. Trying to create working snap package for it and can’t get it working so far and shared memory is one of issues.

I’m also testing the snapcraft-preload part for the firefox snap, for the same reason (firefox tries to write shared memory to /dev/shm/org.chromium.XXXXXX, it uses code from chromium for IPC).
The shim doesn’t seem to have any effect, maybe because firefox launches subprocesses with a “clean” environment, and thus wipes the value of LD_PRELOAD.

I’m also interested in thoughts and suggestions.

doesnt it do that via a wrapper script ? (did you try to patch that ?)

I haven’t tried, and haven’t actually confirmed that this is really what’s happening. Just guessing there.
But even if it did, the point of having a preload part is to not have to patch the upstream code, and in the case of firefox it’s even more important as the snap is basically built out of an existing binary build, it’s not being recompiled just for the snap.

In the particular case of firefox, it is expected to use the transitional browser-support interface, and that interface can be updated for firefox’s use of /dev/shm.

There are two straightforward routes to solving the shared memory issue:

The first one is to prefix the shared memory files snap.<snap name>. This works out of the box without any interfaces.

Here are the specific apparmor rules:

# App-specific access to files and directories in /dev/shm. We allow file
# access in /dev/shm for shm_open() and files in subdirectories for open()
/{dev,run}/shm/snap.@{SNAP_NAME}.** mrwlkix,
# Also allow app-specific access for sem_open()
/{dev,run}/shm/sem.snap.@{SNAP_NAME}.* mrwk,

Then, if the above doesn’t work for you and your application, game, etc needs custom rules along the line of what we have for chromium, we can define a new interface for that. Just let us know about the details and we’ll implement the interface and release on the upcoming snapd.

1 Like

Excellent! I’ve prepared a pull request that adds that exception: https://github.com/snapcore/snapd/pull/4005.

2 Likes

I’ve run into this issue with a python3/Gtk3 app I’m working on (my first snap). I have a large gap in my apparmor knowledge (I know next to nothing about it), so could you clarify where the apparmor rules should be placed/edited/etc? Or have I misunderstood something here (very likely)? Thanks.

EDIT: I now realize that using snapcraft-preload is supposed to change the /dev/shm/ path to be snap-specific (nothing needs to be done in relation to apparmor). However, it’s not clear to me if I can use “snapcraft-preload desktop-launch binary”, or …? I’ll have to work more on this later.

Chaining snapcraft-preload and desktop-launch works fine. In both cases they just set environment variables and then exec the next command on the command-line.

The actual code looks something like this:

#!/bin/bash

export MY_SUPER_ENVIRONMENT=awesome

# chain to the next command - $@ has the commandline without our current filename ($0)
exec "$@"

Do they set some of the same environment variables? I get different results with “command: snapcraft-preload desktop-launch $SNAP/bin/app” than I do with “command: desktop-launch snapcraft-preload $SNAP/bin/app”

Output with “command: snapcraft-preload desktop-launch $SNAP/bin/app”:

mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.cache/gio-modules’ is not a directory
Unable to open directory /home/dev/snap/disk-copy-utility/x18/.cache/gio-modules: Error opening directory ‘/home/dev/snap/disk-copy-utility/x18/.cache/gio-modules’: No such file or directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/glib-2.0/schemas’ is not a directory
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/glib-2.0/schemas’ is not a directory
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/glib-2.0/schemas’ is not a directory
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/glib-2.0/schemas’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Adwaita’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/DMZ-Black’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/DMZ-White’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Humanity’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Humanity-Dark’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/LoginIcons’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/hicolor’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/ubuntu-mono-dark’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/ubuntu-mono-light’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Adwaita’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/DMZ-Black’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/DMZ-White’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Humanity’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/Humanity-Dark’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/LoginIcons’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/hicolor’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/ubuntu-mono-dark’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.local/share/icons/ubuntu-mono-light’ is not a directory
mkdir: cannot create directory ‘/home/dev/snap/disk-copy-utility’: Read-only file system
ln: target ‘/home/dev/snap/disk-copy-utility/x18/.cache/immodules’ is not a directory
/snap/disk-copy-utility/x18/bin/desktop-launch: line 356: /home/dev/snap/disk-copy-utility/x18/.cache/immodules/immodules.cache: No such file or directory
(app:18664): GLib-GIO-ERROR **: No GSettings schemas are installed on the system
Trace/breakpoint trap (core dumped)

command: desktop-launch snapcraft-preload $SNAP/bin/app

(app:19163): GLib-GIO-WARNING **: Error creating IO channel for /proc/mounts: Permission denied (g-file-error-quark, 2)
Traceback (most recent call last):
File “/snap/disk-copy-utility/x19/bin/app”, line 11, in
load_entry_point(‘disk-copy-utility==0.1’, ‘console_scripts’, ‘app’)()
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/pkg_resources/init.py”, line 572, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/pkg_resources/init.py”, line 2752, in load_entry_point
return ep.load()
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/pkg_resources/init.py”, line 2405, in load
return self.resolve()
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/pkg_resources/init.py”, line 2411, in resolve
module = import(self.module_name, fromlist=[‘name’], level=0)
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/disk_copy_utility/app.py”, line 155, in
builder.connect_signals(MainApp())
File “/snap/disk-copy-utility/x19/lib/python3.5/site-packages/disk_copy_utility/app.py”, line 20, in init
self.q = Queue()
File “/snap/disk-copy-utility/x19/usr/lib/python3.5/multiprocessing/context.py”, line 101, in Queue
return Queue(maxsize, ctx=self.get_context())
File “/snap/disk-copy-utility/x19/usr/lib/python3.5/multiprocessing/queues.py”, line 42, in init
self._rlock = ctx.Lock()
File “/snap/disk-copy-utility/x19/usr/lib/python3.5/multiprocessing/context.py”, line 66, in Lock
return Lock(ctx=self.get_context())
File “/snap/disk-copy-utility/x19/usr/lib/python3.5/multiprocessing/synchronize.py”, line 163, in init
SemLock.init(self, SEMAPHORE, 1, 1, ctx=ctx)
File “/snap/disk-copy-utility/x19/usr/lib/python3.5/multiprocessing/synchronize.py”, line 60, in init
unlink_now)
PermissionError: [Errno 13] Permission denied

I assume the first option (snapcraft-preload then desktop-launch) is “progress”, since otherwise I seem to get the same issue as before with the second option (desktop-launch then snapcraft-preload).

Ok, yes, I forgot that the desktop-launch will get intercepted by the snapcraft-preload, so desktop-launch should be before snapcraft-preload in the chain.

As to the error, you’re receiving a permission denied trying to access /proc/mounts which can be fixed by plugging mount-observe and manually connecting it with sudo snap connect your-snap:mount-observe. Could you raise further issues in a separate topic please, as this topic is related to /dev/shm and discussing tangentially will confuse other readers of our conversation.