cmd,tests: fix classic confinement confusing re-execution code #3598

Merged
merged 4 commits into from Jul 18, 2017

Conversation

Projects
None yet
4 participants
Contributor

zyga commented Jul 17, 2017

When snapd inside the core snap is more recent than the snapd in the
classic distribution and the classic distribution supports snapd
re-execution then certain tools, namely snap and snapd will re-execute
the version of themselves found in the core snap.

To prevent endless loops as a part of this re-execution the variable
SNAP_DID_REEXEC is to 1 and tested in the re-execution mechanism.

Snaps using classic confinement do not get a mount namespace rooted at
the core (or designated base) snap and instead share the classic mount
namespace. As such their /usr/bin/snap is the one from the distribution
package.

When those two features are combined, a snap using classic confinement
will run with SNAP_DID_REEXEC=1 and /usr/bin/snap being the one from the
distribution. If such snap now runs a snap command, it will couple
potentially older /usr/bin/snap (e.g. from 2.25) with the profiles from
potentially newer /usr/bin/snapd (e.g. from 2.26.9). That specific
combination crosses the threshold where snap-seccomp begins to be used
and thus the old snap-confine cannot run new applications.

As a fix, unset SNAP_DID_REEXEC after observing the value 1, this will
ensure that the execution environment will not contain that flag and
each subsequent attempt to run /usr/bin/snap will re-consider
re-execution correctly.

Fixes: https://bugs.launchpad.net/snapd/+bug/1704860
Forum: https://forum.snapcraft.io/t/snapd-2-26-9-and-conjure-up-no-longer-work/
Signed-off-by: Zygmunt Krynicki zygmunt.krynicki@canonical.com

@zyga zyga changed the title from tests: add test case for classic-schizofrenia-bug to cmd,tests: fix classic confinement confusing re-execution code Jul 17, 2017

@zyga zyga added the Critical label Jul 17, 2017

cmd,tests: fix classic confinement confusing re-execution code
When snapd inside the core snap is more recent than the snapd in the
classic distribution and the classic distribution supports snapd
re-execution then certain tools, namely snap and snapd will re-execute
the version of themselves found in the core snap.

To prevent endless loops as a part of this re-execution the variable
SNAP_DID_REEXEC is to 1 and tested in the re-execution mechanism.

Snaps using classic confinement do not get a mount namespace rooted at
the core (or designated base) snap and instead share the classic mount
namespace. As such their /usr/bin/snap is the one from the distribution
package.

When those two features are combined, a snap using classic confinement
will run with SNAP_DID_REEXEC=1 and /usr/bin/snap being the one from the
distribution. If such snap now runs a snap command, it will couple
potentially older /usr/bin/snap (e.g. from 2.25) with the profiles from
potentially newer /usr/bin/snapd (e.g. from 2.26.9). That specific
combination crosses the threshold where snap-seccomp begins to be used
and thus the old snap-confine cannot run new applications.

As a fix, unset SNAP_DID_REEXEC after observing the value 1, this will
ensure that the execution environment will *not* contain that flag and
each subsequent attempt to run /usr/bin/snap will re-consider
re-execution correctly.

Fixes: https://bugs.launchpad.net/snapd/+bug/1704860
Forum: https://forum.snapcraft.io/t/snapd-2-26-9-and-conjure-up-no-longer-work/
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

mvo5 approved these changes Jul 18, 2017

Thanks for fixing this one!

zyga and others added some commits Jul 18, 2017

cmd: log one more possible error branch
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

Codecov Report

Merging #3598 into master will decrease coverage by 1.9%.
The diff coverage is 33.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3598      +/-   ##
==========================================
- Coverage    76.8%   74.89%   -1.91%     
==========================================
  Files         380      380              
  Lines       26390    32951    +6561     
==========================================
+ Hits        20269    24680    +4411     
- Misses       4329     6478    +2149     
- Partials     1792     1793       +1
Impacted Files Coverage Δ
cmd/cmd.go 88.37% <33.33%> (-2.4%) ⬇️
interfaces/builtin/framebuffer.go 48.83% <0%> (-16.69%) ⬇️
osutil/bootid.go 45.45% <0%> (-10.11%) ⬇️
interfaces/kmod/kmod.go 45.45% <0%> (-10.11%) ⬇️
interfaces/mount/lock.go 45.45% <0%> (-10.11%) ⬇️
cmd/snap/cmd_prefer.go 42.85% <0%> (-10.09%) ⬇️
cmd/snap/cmd_unalias.go 42.85% <0%> (-10.09%) ⬇️
overlord/snapstate/backend/utils.go 50% <0%> (-10%) ⬇️
osutil/digest.go 50% <0%> (-10%) ⬇️
cmd/snap/cmd_managed.go 53.84% <0%> (-9.8%) ⬇️
... and 317 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b68317c...9178aac. Read the comment docs.

@@ -156,6 +158,9 @@ func ExecInCoreSnap() {
// Did we already re-exec?
if osutil.GetenvBool("SNAP_DID_REEXEC") {
+ if err := os.Unsetenv("SNAP_DID_REEXEC"); err != nil {
+ panic(fmt.Sprintf("cannot unset SNAP_DID_REEXEC: %s", err))
@chipaca

chipaca Jul 18, 2017

Member

or logger.Panicf (not worth the test time at this point)

@zyga zyga merged commit e2c69c3 into snapcore:master Jul 18, 2017

1 of 7 checks passed

artful-amd64 autopkgtest running
Details
xenial-amd64 autopkgtest running
Details
xenial-i386 autopkgtest running
Details
xenial-ppc64el autopkgtest running
Details
yakkety-amd64 autopkgtest running
Details
zesty-amd64 autopkgtest running
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

sergiocazzolato added a commit to sergiocazzolato/snapd that referenced this pull request Jul 18, 2017

cmd,tests: fix classic confinement confusing re-execution code (#3598)
cmd,tests: fix classic confinement confusing re-execution code

When snapd inside the core snap is more recent than the snapd in the
classic distribution and the classic distribution supports snapd
re-execution then certain tools, namely snap and snapd will re-execute
the version of themselves found in the core snap.

To prevent endless loops as a part of this re-execution the variable
SNAP_DID_REEXEC is to 1 and tested in the re-execution mechanism.

Snaps using classic confinement do not get a mount namespace rooted at
the core (or designated base) snap and instead share the classic mount
namespace. As such their /usr/bin/snap is the one from the distribution
package.

When those two features are combined, a snap using classic confinement
will run with SNAP_DID_REEXEC=1 and /usr/bin/snap being the one from the
distribution. If such snap now runs a snap command, it will couple
potentially older /usr/bin/snap (e.g. from 2.25) with the profiles from
potentially newer /usr/bin/snapd (e.g. from 2.26.9). That specific
combination crosses the threshold where snap-seccomp begins to be used
and thus the old snap-confine cannot run new applications.

As a fix, unset SNAP_DID_REEXEC after observing the value 1, this will
ensure that the execution environment will *not* contain that flag and
each subsequent attempt to run /usr/bin/snap will re-consider
re-execution correctly.

Fixes: https://bugs.launchpad.net/snapd/+bug/1704860
Forum: https://forum.snapcraft.io/t/snapd-2-26-9-and-conjure-up-no-longer-work/
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

zyga added a commit to zyga/snapd that referenced this pull request Aug 7, 2017

cmd,tests: fix classic confinement confusing re-execution code (#3598)
cmd,tests: fix classic confinement confusing re-execution code

When snapd inside the core snap is more recent than the snapd in the
classic distribution and the classic distribution supports snapd
re-execution then certain tools, namely snap and snapd will re-execute
the version of themselves found in the core snap.

To prevent endless loops as a part of this re-execution the variable
SNAP_DID_REEXEC is to 1 and tested in the re-execution mechanism.

Snaps using classic confinement do not get a mount namespace rooted at
the core (or designated base) snap and instead share the classic mount
namespace. As such their /usr/bin/snap is the one from the distribution
package.

When those two features are combined, a snap using classic confinement
will run with SNAP_DID_REEXEC=1 and /usr/bin/snap being the one from the
distribution. If such snap now runs a snap command, it will couple
potentially older /usr/bin/snap (e.g. from 2.25) with the profiles from
potentially newer /usr/bin/snapd (e.g. from 2.26.9). That specific
combination crosses the threshold where snap-seccomp begins to be used
and thus the old snap-confine cannot run new applications.

As a fix, unset SNAP_DID_REEXEC after observing the value 1, this will
ensure that the execution environment will *not* contain that flag and
each subsequent attempt to run /usr/bin/snap will re-consider
re-execution correctly.

Fixes: https://bugs.launchpad.net/snapd/+bug/1704860
Forum: https://forum.snapcraft.io/t/snapd-2-26-9-and-conjure-up-no-longer-work/
Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

mvo5 added a commit that referenced this pull request Aug 7, 2017

Merge pull request #3674 from zyga/backport/more-fixes
cmd,tests: fix classic confinement confusing re-execution code (#3598)

@zyga zyga deleted the zyga:fix/clasic-schizofrenia-bug branch Aug 22, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment