Apparmor: issues with default @{INSTALL_DIR}

I’ve installed snapd with apparmor support on Archlinux distro. Among various issues which I already reported, there is a problem with default @{INSTALL_DIR} path in apparmor profiles for snap applications.

Currently it’s set as:
@{INSTALL_DIR}="/snap"

But on my system starting an app always fails with:

AVC apparmor="DENIED" operation="open" profile="snap.qownnotes.qownnotes" name="/var/lib/snapd/snap/qownnotes/906/meta/snap.yaml" pid=4640 comm="snap-exec" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

Changing it to: @{INSTALL_DIR}="/var/lib/snapd/snap" fails with:

AVC apparmor="DENIED" operation="exec" profile="snap.qownnotes.qownnotes" name="/snap/qownnotes/906/bin/desktop-launch" pid=4462 comm="command-qownnot" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0

I can fix it by changing above line to:
@{INSTALL_DIR}="/{,var/lib/snapd/}snap"

The /snap top directory doesn’t exist on my host system but it does inside sandbox:
snap run --shell qownnotes
ls /
bin boot dev etc home lib lib64 media meta mnt opt proc root run sbin snap srv sys tmp usr var writable

It looks like /var/lib/snapd/snap/qownnotes/906/meta/snap.yaml is accessed outside app sandbox (before sandbox it’s created?) thus /snap path is invalid there.

I tested it with snapd 2.31.2 and master branch from git.

You need to do this currently. I suggest the following:

diff -Naur snapd-2.31.orig/interfaces/apparmor/template_vars.go snapd-2.31/interfaces/apparmor/template_vars.go
--- snapd-2.31.orig/interfaces/apparmor/template_vars.go	2018-02-14 17:32:12.000000000 +0000
+++ snapd-2.31/interfaces/apparmor/template_vars.go	2018-02-14 15:12:57.000000000 +0000
@@ -23,6 +23,7 @@
 	"bytes"
 	"fmt"
 
+	"github.com/snapcore/snapd/dirs"
 	"github.com/snapcore/snapd/interfaces/dbus"
 	"github.com/snapcore/snapd/snap"
 )
@@ -35,6 +36,11 @@
 	fmt.Fprintf(&buf, "@{SNAP_REVISION}=\"%s\"\n", info.Revision)
 	fmt.Fprintf(&buf, "@{PROFILE_DBUS}=\"%s\"\n",
 		dbus.SafePath(securityTag))
-	fmt.Fprintf(&buf, "@{INSTALL_DIR}=\"/snap\"")
+
+	if dirs.SnapMountDir == "/snap" {
+		fmt.Fprintf(&buf, "@{INSTALL_DIR}=\"/snap\"")
+	} else {
+		fmt.Fprintf(&buf, "@{INSTALL_DIR}=\"{/snap,%s}\"", dirs.SnapMountDir)
+	}
 	return buf.String()
 }

snap-exec could perhaps be adjusted to look in only /snap for meta/snap.yaml when !classic since, like you said, with strict/devmode /snap is going to exist in the snap’s mount namespace.

@jdstrand
I tested your patch. It sets:
@{INSTALL_DIR}="{/snap,/var/lib/snapd/snap}"
but it works for me.

I wonder why this is needed since snap-exec only sees the world after pivot_root. It should never see the /var/lib/snapd/snap directory unless we actually set $SNAP to that value.

I don’t know if that helps but here’s strace output when @{INSTALL_DIR}="/snap"

https://paste.ubuntu.com/p/4w9psC755y/

Solved in https://github.com/snapcore/snapd/commit/a244e64934bcdda72ee6e96ef98f60c9826af3a0