Support preloading to make snaps feel at home

Bug #1577514 reported by Sergio Schvezov on 2016-05-02
48
This bug affects 8 people
Affects Status Importance Assigned to Milestone
Snapcraft
High
Sergio Schvezov

Bug Description

Electron apps, based out of chromium, create shared memory files of the form /dev/shm/.org.chromium.Chromium.XXXX which is not supported by apparmor

The root issue is the same as what is mentioned in LP: #1260103

For the full back story and ideas:
- https://lists.ubuntu.com/archives/snappy-devel/2016-May/001796.html
- https://lists.ubuntu.com/archives/snappy-devel/2016-May/001798.html

Zygmunt Krynicki (zyga) on 2016-05-03
Changed in snappy:
status: New → Confirmed
Jamie Strandboge (jdstrand) wrote :

This is related to bug #1578217.

Jamie Strandboge (jdstrand) wrote :

Gustavo and I discussed this on IRC today.

Here is the problem: chromium content api hard codes /dev/shm/.org.chromium.Chromium.XXXX (where 'XXXX' is tmpfile-style name). There are many consumers of the chromium content api (eg, electron, oxide-qt, webbrowser-app, Google Chrome, Opera, chromium, etc).

Discarded possible solutions include:
1. force patching
2. allow all apps to access .org.chromium.Chromium.*
3. allow only one snap to access the path

For '1', asking developers to patch chromium to 's/\.org\.chromium\.Chromium/snap.$SNAP_NAME/' would be onerous and unfriendly. '2' does not provide proper application isolation and snaps could access each other's data and '3' means you couldn't have say, an electron app and Chrome installed at the same time.

Zygmunt created a PoC LD_PRELOAD library for shm_open() as an exploration into the problem space and should work well for shm_open() users, but chromium content api uses open() for portability reasons so the LD_PRELOAD library should also handle open(), doing a check to see if the requested path to open matches /dev/shm/.org.chromium... (should also handle /run/shm!) then to replace it with /dev/shm/snap.$SNAP_NAME.org.chromium... to conform to the new snappy architect-approved shm paths.

Gustavo Niemeyer (niemeyer) wrote :

As a minor detail, we should build this as a generic library that can be reused for other similar cases. I suggest supporting the DEV_SHM_PREFIX (for chromium it'd be set to ".org.chromium.Chromium", for example), and using SNAP_NAME on the replacement which should already be in the process space.

We have a pretty good relationship with Chrome upstream, we could offer
up a patch if that would help.

Mark

We agreed today to create a shared part (wiki part) for this to allow people to easily get around the issue without patching everything single electron build.

@sabdfl the issue is not chromium itself but electron which forks chromium. In due time we should be able to patch every single fork of chromium but we also need some quick path to happiness which is what is being discussed in this bug.

affects: snappy → snapcraft
Changed in snapcraft:
importance: Undecided → High
assignee: nobody → Sergio Schvezov (sergiusens)
Changed in snapcraft:
milestone: none → 2.11
status: Confirmed → Triaged
summary: - Allow out of the box use of chromium based apps
+ Support preloading to make snaps feel at home
Changed in snapcraft:
milestone: 2.12 → 2.13
Changed in snapcraft:
milestone: 2.13 → 2.14
Changed in snapcraft:
milestone: 2.13 → none
Jamie Strandboge (jdstrand) wrote :

This came up again on IRC today and I wanted to point to the plan of record and noticed it didn't exist here (perhaps it is somewhere else?). I've heard this talked about in other places but didn't see the outcome explicitly listed here. AIUI, what Gustavo (please correct me if I'm wrong! :) has laid out is:

1. a generic preload library that is capable of mapping directories/files/named sockets from one place to another
2. a way to declare in the packaging yaml what should be mapped (eg, /etc/foo to $SNAP_DATA/etc/foo)
3. on application launch, the declared mappings are exported as env vars that the generic library interprets and the library is LD_PRELOADed.

In this manner there are no code changes and the packaging yaml need only be adjusted. This would allow us to easily handle Chrome and a whole bunch of other software.

As for the current situation (ie, while the above is not implemented) with shm and the chromium issue in particular, in addition to what Sergio suggested snapcraft will do for electron, snapd now has security policy to allow '/{dev,run}/shm/snap.@{SNAP_NAME}.** mrwlkix,' so developers are free to patch their code to make things work today regardless of open() or shm_open() usage. We've also engaged with upstream Chrome to see if they are open to adjusting the shm path (waiting to hear back). Oxide is currently being adjusted to use a path that conforms to the aforementioned allowed path.

@Jamie Bennett, it isn't clear (to me and others I've spoken to on IRC) where this should be implemented and by whom (ie, snapd vs snapcraft) and at what priority. I see Sergio is assigned, but not sure if that is for his electron work or for the generic library. Perhaps the priority of this can be discussed for a few minutes at the sprint?

Sam Yaple (s8m) wrote :

jdstrand asked me to comment here (I believe I was the "This came up again on IRC today" from the previous comment).

The situation I face is packaging OpenStack with snappy and working with other OpenStack projects for deployment (specifically OpenStack-Ansible). I don't always have control over where it is going to lay down config files. If I could map /etc/foo into ${SNAP_DATA}/etc/foo this would work beautifully.

While that may be a very specific use case, having the ability to map in /etc/foo allows for the seamless transition from traditional packages to snappy. I can't imagine this will do anything but drive up adoption.

keshavbhatt (keshavnrj) wrote :

same happening with nwjs applications, nwjs is also based of chromium project and hence the application written on nwjs api cant run when packaged in snap format.

I ported my application from qt to nwjs cause same issue are happening with qwebengine which is again the based on chromium web engine qt migrated from webkit to chromium based webengine so, so Qt web-based application cant be packaged cause they will result in runtime crash.

- ERROR in strict confinement

= AppArmor =
Time: Dec 20 20:21:47
Log: apparmor="DENIED" operation="mknod" profile="snap.simple-gulp.messenger-snap" name="/dev/shm/.io.nwjs.MMIb0o" pid=9069 comm="Chrome_IOThread" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
File: /dev/shm/.io.nwjs.MMIb0o (write)
Suggestion:
* adjust program to create files and directories in /dev/shm/snap.$SNAP_NAME.*

- ERROR in devmode confinement

= AppArmor =
Time: Dec 20 21:27:04
Log: apparmor="ALLOWED" operation="truncate" profile="snap.simple-gulp.messenger-snap" name="/dev/shm/.io.nwjs.onU4pg" pid=10628 comm="Chrome_FileUser" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000
File: /dev/shm/.io.nwjs.onU4pg (write)
Suggestion:
* adjust program to create files and directories in /dev/shm/snap.$SNAP_NAME.*

I also tried below in my wrapper script to change XDG_RUNTIME_DIR but it wont affect application from writing only to /dev/shm/ -- based on https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html

export XDG_RUNTIME_DIR=$XDG_CACHE_HOME/$SNAP_NAME/
mkdir -p $XDG_RUNTIME_DIR

tags: added: isv
Sergio Schvezov (sergiusens) wrote :

we have a preload part that should cover this scenario

Changed in snapcraft:
status: Triaged → Opinion
Olivier Tilloy (osomon) wrote :

Unfortunately preloading does not fix all use cases, such as the one where an app launches sub-processes in a clean environment, thus not passing down the value of $LD_PRELOAD (see https://forum.snapcraft.io/t/shared-memory-in-dev-shm-rewriting/2023).

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers