cmd: fix re-exec bug with classic confinement for host snapd < 2.28 #4176

Merged
merged 2 commits into from Nov 9, 2017
Jump to file or symbol
Failed to load files and symbols.
+28 −1
Split
View
@@ -176,6 +176,15 @@ func ExecInCoreSnap() {
// Did we already re-exec?
if strings.HasPrefix(exe, dirs.SnapMountDir) {
+ // Older version of snapd (before 2.28) did use this env
+ // to check if they should re-exec or not. We still need
+ // to unset it because the host snap tool may be old and
+ // using this key. So if e.g. the host has snapd 2.27 and
+ // snapd re-execs to 2.29 then `snap run --shell classic-snap`
+ // will go into an environment where the snapd 2.27 sees
+ // this key and stops re-execing - which is not what we
+ // want. C.f. https://forum.snapcraft.io/t/seccomp-error-calling-snap-from-another-classic-snap-on-core-candidate/2736/7
+ mustUnsetenv("SNAP_DID_REEXEC")
return
}
View
@@ -293,6 +293,7 @@ func (s *cmdSuite) TestExecInCoreSnapNoDouble(c *C) {
selfExe := filepath.Join(s.fakeroot, "proc/self/exe")
err := os.Symlink(filepath.Join(s.fakeroot, "/snap/core/42/usr/lib/snapd"), selfExe)
c.Assert(err, IsNil)
+ cmd.MockSelfExe(selfExe)
cmd.ExecInCoreSnap()
c.Check(s.execCalled, Equals, 0)
@@ -307,3 +308,17 @@ func (s *cmdSuite) TestExecInCoreSnapDisabled(c *C) {
cmd.ExecInCoreSnap()
c.Check(s.execCalled, Equals, 0)
}
+
+func (s *cmdSuite) TestExecInCoreSnapUnsetsDidReexec(c *C) {
+ os.Setenv("SNAP_DID_REEXEC", "1")
+ defer os.Unsetenv("SNAP_DID_REEXEC")
+
+ selfExe := filepath.Join(s.fakeroot, "proc/self/exe")
+ err := os.Symlink(filepath.Join(s.fakeroot, "/snap/core/42/usr/lib/snapd"), selfExe)
+ c.Assert(err, IsNil)
+ cmd.MockSelfExe(selfExe)
+
+ cmd.ExecInCoreSnap()
+ c.Check(s.execCalled, Equals, 0)
+ c.Check(os.Getenv("SNAP_DID_REEXEC"), Equals, "")
+}
@@ -19,4 +19,7 @@ execute: |
. $TESTSLIB/snaps.sh
install_local_classic test-snapd-classic-confinement
# We don't want to see SNAP_DID_REEXEC being set.
- snap run --shell test-snapd-classic-confinement ./snap-env-query.sh | MATCH -v 'SNAP_DID_REEXEC='
+ if snap run --shell test-snapd-classic-confinement ./snap-env-query.sh | grep 'SNAP_DID_REEXEC='; then
+ echo "SNAP_DID_REEXEC environment is not reset as it should be"
+ exit 1
+ fi