Apparmor Problem Snap in strict confinement

I have created a snap for a commandline program which runs fine in devmode. In strict confinement mode I am running into AppArmor violations which I am trying to debug.

The Log I am getting:

Feb 13 18:41:45 alexander-XPS-13-9350 audit[38683]: AVC apparmor="DENIED" operation="mknod" profile="snap.ocrmypdf.ocrmypdf" name="/dev/shm/wxhY1f" pid=38683 comm="python3.9" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
Feb 13 18:41:45 alexander-XPS-13-9350 kernel: audit: type=1400 audit(1644774105.530:1257): apparmor="DENIED" operation="mknod" profile="snap.ocrmypdf.ocrmypdf" name="/dev/shm/wxhY1f" pid=38683 comm="python3.9" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
Feb 13 18:41:45 alexander-XPS-13-9350 audit[38683]: AVC apparmor="DENIED" operation="mknod" profile="snap.ocrmypdf.ocrmypdf" name="/dev/shm/3lTOMc" pid=38683 comm="python3.9" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
Feb 13 18:41:45 alexander-XPS-13-9350 kernel: audit: type=1400 audit(1644774105.538:1258): apparmor="DENIED" operation="mknod" profile="snap.ocrmypdf.ocrmypdf" name="/dev/shm/3lTOMc" pid=38683 comm="python3.9" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000

I am trying to access a file in /home/downloads The “home” Plug is added to “Plugs” in the snapcraft.yaml and the output of

alexander@alexander-XPS-13-9350:~$ snap connections ocrmypdf
Interface        Plug                      Slot             Notes
desktop          ocrmypdf:desktop          :desktop         -
desktop-legacy   ocrmypdf:desktop-legacy   :desktop-legacy  -
home             ocrmypdf:home             :home            -
removable-media  ocrmypdf:removable-media  -                -
wayland          ocrmypdf:wayland          :wayland         -
x11              ocrmypdf:x11              :x11             -

seems to me to be ok

Any Ideas what I am missing?

My snapcraft.yaml is here:

I am using a custom path to python3.9 due to a bug in the python plugin in core20:

Your apparmor denials would suggest this is a problem with the use of the /dev/shm folder.

The default policy is that files created in /dev/shm must be namespaced to the snap, such that any temporary files follow the pattern of SNAP.$SNAPNAME.* (or something similar, I can’t 100% remember it :wink: ).

There’s a proposal for these kind of issues that might remove this restriction in the future, take a look here, but none of this is available to use yet.

Your options are likely to either use the snapcraft-preload library which can fix this in some situations (by mapping transparently renaming files so they work), but it may be the case that whatever is making this call in Python is actually avoiding the standard shm_open() calls. E.G, Joblib in Python tests if /dev/shm/ exists first by just placing any random file in it, which fails and causes issues. If it’s a case similar to this, you might need to patch the Python file causing the issue (e.g, with sed or patch).

I have added snapcraft-preload to my snapcraft.yaml.

Following the instructions here:

I added:

    command: bin/snapcraft-preload $SNAP/bin/python3.9 -m ocrmypdf

which yields:

Failed to generate snap metadata: The specified command 'bin/snapcraft-preload $SNAP/bin/python3.9 -m ocrmypdf' defined in the app 'ocrmypdf' does not exist.
Ensure that 'bin/snapcraft-preload $SNAP/bin/python3.9 -m ocrmypdf' is installed with the correct path.

The path /prime/bin/python3.9 does exist when I introspect the build error.

Judging by the error message, iIt is likely that it is bin/snapcraft-preload that it can’t find.

you appear to be correct… but why? there is no prime/bin/snapcraft-preload

there is no prime/bin/snapcraft-preload

find prime -name snapcraft-preload

found it in prime/usr/local/bin/snapcraft-preload

the tutorial info here: https://github.com/sergiusens/snapcraft-preload points to a different location. I had not expected the path to change from core18

1 Like

I am now currently stuck at:

ERROR: ld.so: object '/snap/ocrmypdf/10/lib/libsnapcraft-preload.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

$SNAP/lib/libsnapcraft-preload.so indeed does not exist.

snap run --shell ocrmypdf
ls $SNAP | grep preload

returns nothing.

Any Idea as to why snapcraft preload does not seem to do anything?

that would not list content of subdirs (so it would never find the file in lib/ )…

try rather:

find $SNAP -name '*preload*'

I found the file in:

/usr/local/lib

How do I tell the snap in which directory to look for this library?

you might need to add:

      cmake-parameters:
        - -DCMAKE_INSTALL_PREFIX=/usr -DLIBPATH=/lib

to have the bits installed in the right locations (base: core18 snaps do this automatically, in base: core20 builds prefix and libpath have no defaults set)

that did help!

Now I have my project generating a snap. Unfortunately snapcraft seems to be ignoring my:

python-packages:
- list items

This problem has appeared because core20 in strict confinement does not seem to have python bundled in (at least I cannot find python anywhere in the snap).

So I added the stage-packages:

 stage-packages:
 - libpython3-stdlib
 - libpython3.8-stdlib
 - libpython3.8-minimal
 - python3-pip
 - python3-setuptools
 - python3-wheel
 - python3-venv
 - python3-minimal
 - python3-distutils
 - python3-pkg-resources
 - python3.8-minimal

This feels like I am doing something wrong. The documentation here: https://snapcraft.io/docs/python-plugin states that there should be a python interpreter included in core20. -> Found the solution to this: just use the python3 command to invoke python and NOT a full path to a python interpreter. This will use the default interpreter in core20

I believe that snapcraft is ignoring my python-packages list ever since I manually included python in the stage-packages… -> This was an incorrect belief. PIP is not used because of the override-build I used to get snapcraft-preload to work.

Will update if I get it to work…

The solution is outlined here:

The problem was:

  1. apparmor blocks the python code as it is -> requires snapcraft-preload to work
  2. snapcraft-preload on core20 is not installed where it is expected and requires override-build symlinking to work
  3. override-build requires explicitely stating snapcraftctl build in the override-build section (see documentation here: https://snapcraft.io/docs/scriptlets)

Thanks to everyone who helped in fixing this!