Help creating a strict snap that uses shared memory

Hi,

I’m trying to run sublime-text with strict confinement but fails when trying to access shared memory in /dev/shm

I asked the developer for support for /{dev,run}/shm/snap.@{SNAP_INSTANCE_NAME}
( https://forum.sublimetext.com/t/snap-with-strict-confinment/56405 )

They pointed me to this workaround https://forum.snapcraft.io/t/snap-interface-for-dev-shm/6939/5

Where and how do I have to do this after creating my snap:

$ mkdir /dev/shm/shared
$ mkdir ~/shmdir
$ sudo mount --bind /dev/shm/shared ~/shmdir
$ touch ~/shmdir/foo
$ ls /dev/shm/shared/
foo

this is rather a gross hack a user could apply manually, not a workaround that you could do from within a snap at all

I need to know how to do the hack

I wont publish the snap, I just need to run sublime-text confined

well, just copy/paste the lines to your terminal … then navigate in sublimes file chooser to ~/shmdir and you should be able to load/save files in /dev/shm to share them with other apps … (which is what the other thread was about)

If you’re creating your own sublimes-text snap, you probably can take a look this preloader.
It could override the path before really opening the target file.

1 Like

The executable is using shared memory, I don’t want to use shared memory!

When running sublime-text I get:

Mar 03 16:10:46 hostname kernel: audit: type=1400 audit(1614787846.542:126807): apparmor=“DENIED” operation=“mknod” profile=“snap.sublime-text.subl” name="/dev/shm/122560:subl_api_send" pid=122560 comm=“sublime_text” requested_mask=“c” denied_mask=“c” fsuid=1000 ouid=1000

Is there a workaround so I can run sublime-text on strict confinement ?

yes, that is what i expected … the thread with the “workaround” you linked has nothing to do with that, it is about being able to share files between apps though /dev/shm

try the preloader trick that robert pointed to …

1 Like

The link to the preload wrapper that @robertliu posted above is your best chance at getting it working…

1 Like

I build my snap adding this part:

snapcraft-preload:
source: https://github.com/sergiusens/snapcraft-preload.git
plugin: cmake
build-packages:
- on amd64:
- gcc-multilib
- g+±multilib

And now use as command:

command: usr/local/bin/snapcraft-preload $SNAP/opt/sublime_text/sublime_text

But I get this error:

ERROR: ld.so: object ‘/snap/sublime-text/x1/lib/libsnapcraft-preload.so’ from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

Any help with this!

well, for whatever strage reason the snapcraft-preload stuff seems to have landed in $SNAP/usr/local instead of the toplevel of $SNAP … not sure how that could happen if you didnt tinker with LIBPATH

I think core20 builds might put them in /usr/local by default now… right, @cjp256?

When building step by step I find

snapcraft-sublime-text # ls /root/parts/snapcraft-preload/install/usr/local/lib/
libsnapcraft-preload32.so libsnapcraft-preload.so

and

snapcraft-sublime-text # ls /root/stage/usr/local/lib/
libsnapcraft-preload32.so libsnapcraft-preload.so

And on the installed snap:

federico # ls /snap/sublime-text/current/usr/local/lib/
libsnapcraft-preload.so libsnapcraft-preload32.so

so you probably want to patch usr/local/bin/snapcraft-preload to point to usr/local/lib instead of just lib/

though if thats really a snapcraft induced change as @lucyllewy suggests that smells really messy

(i personally often take quite some effort to not have such mess inside my snaps and have the prefix point properly to the toplevel $SNAP, having things default to add pointless directory struture that you need to compensate via hacks later feels very wrong)

1 Like

I usually set whatever build system to use a prefix of /usr so that it is most similar to what a deb package would have done

yeah usr/ is fine as is / … i just dont want to also have usr/local/ in my snaps (and potentially have to patch common launchers and whatnot to make them respect this)

This organize fix it. I don’t know how to path usr/local/bin/snapcraft-preload to point to usr/local/lib instead of just lib/

parts:
snapcraft-preload:
source: https://github.com/sergiusens/snapcraft-preload.git
plugin: cmake
organize:
“usr/local/bin/": bin/
"usr/local/lib/
”: lib/
build-packages:
- on amd64:
- gcc-multilib
- g+±multilib

1 Like

core20 does not specify cmake parameters by default. You’ll want to add one for the CMAKE_INSTALL_PREFIX, like so:

parts:
  hello:
    plugin: cmake
    cmake-parameters:
      - -DCMAKE_INSTALL_PREFIX=/usr
    ....

Admittedly we probably should have set this as a default parameter, but that boat has sailed now (as introducing that would break existing snaps relying on /usr/local).

2 Likes

@degville, is this change documented anywhere? I haven’t seen a migration guide for bringing a core18 snap up to core20 so if there isn’t one yet that would be a nice idea :slight_smile: (I’m thinking I might have simply overlooked it)

1 Like

If you are only changing the readme of preload to take this into account, maybe also add these lines to fix this warning:

The ‘snapcraft-preload’ part is missing libraries that are not included in the snap or base.
They can be satisfied by adding the following entry for this part
stage-packages:
lib32stdc++6

https://snapcraft.io/docs/cmake-plugin

I believe work on a migration guide is underway, but for the time being I added some documentation for this case @ The cmake plugin | Snapcraft documentation.

1 Like