Hard coded absolute paths

How can you remap file access with hardcoded absolute paths inside a snap?

I want to create a classic snap of a program that calls executables located at /usr/libexec/ but that are actually located in the mounted snap at /snap/<name>/<version>/usr/libexec/.

According to https://snapcraft.io/docs/snap-layouts, this can be solved with layouts. I defined the layout

layout:
  /usr/libexec:
    bind: $SNAP/usr/libexec

that should map all access to /usr/libexec to /snap/<name>/<version>/usr/libexec/.
However, it does not seem to have an effect. The program still fails to find the executables.

Details:

I am trying to snap the Wayland compositor Weston.
Excerpt (full file at https://raw.githubusercontent.com/christianrauch/weston-snap/master/snapcraft.yaml):

confinement: classic
base: core18

environment:
  WESTON_MODULE_MAP: "gl-renderer.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/gl-renderer.so;remoting-plugin.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/remoting-plugin.so;drm-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/drm-backend.so;fbdev-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/fbdev-backend.so;headless-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/headless-backend.so;rdp-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/rdp-backend.so;wayland-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/wayland-backend.so;x11-backend.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/libweston-7/x11-backend.so;desktop-shell.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/weston/desktop-shell.so;fullscreen-shell.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/weston/fullscreen-shell.so;ivi-shell.so=${SNAP}/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/weston/ivi-shell.so"

parts:
  weston:
    plugin: meson
    meson-parameters:
      - --prefix=/usr
      - --pkg-config-path=$SNAPCRAFT_STAGE/share/pkgconfig
    prime:
      - usr/bin
      - usr/lib
      - usr/libexec
      - usr/share/wayland-sessions/weston.desktop
      - usr/share/X11/xkb

layout:
  /usr/libexec:
    bind: $SNAP/usr/libexec

apps:
  weston:
    command: bin/desktop-launch $SNAP/usr/bin/weston
    desktop: usr/share/wayland-sessions/weston.desktop
    plugs:
      - desktop
      - network
      - home
      - wayland
      - x11
      - opengl

When starting Weston, it will try to open /usr/libexec/weston-keyboard, which should resolve to /snap/<name>/<version>/usr/libexec/weston-keyboard.

Hello

Snaps using classic confinement cannot use layouts because they don’t have a mount namespace to customise without affecting the host. There’s a missing bit of validation that says layouts are incompatible with classic confinement.

I’m afraid you need to patch the source code of the program you are packaging to get the desired effect.

Indeed, in devmode this seems to work.
An error message in snapcraft a la “layout not supported in classic confinement” would have been very useful.

1 Like

I agree, the runtime issuing a warning or blocking installation might also be a good idea, @chipaca what are your thoughts?

We could tackle this from both ends - put a warning when building a snap with snapcraft, and another warning from snap/snapd when you try to install a snap with such a configuration

We could print a warning when checking interfaces, and that’d get picked up by check-skeleton…?

Sounds good to me if the plan is to eventually support layouts on classic.

I think the validation of the snap should happen at built time via snapcraft and it should be a critical error as it will render the snap unusable.

It’s not clear to me why layout cannot work in classic confinement. Is there a technical reason, why bind mount or symlinks will not work in classic confinement?

the reason I mention runtime too is that snapcraft is not the only tool available to create a snap.

How layouts work with strict confinement is by performing a series of modifications to the snap’s root filesystem using mounts, even if the method is using a symlink because the “layout” dir that is being modified may be read-only and needs to be modified.

This only works for snaps because those modifications are made inside the snap specific mount namespace and as such only are presented to the snap processes. With a classic snap, we don’t enter (yet) a mount namespace for the snap, and so any modifications that snapd did would end up modifying the root mount namespace and would effectively just end up changing your host filesystem and not be isolated to the snap processes specifically.

AFAIK, this is on the roadmap, but before we get to this, we will be working on parallel installs of classic snaps, which also require a snap mount namespace, so we may be able to add layouts to classic snaps after we get parallel installs working.

1 Like