SNAP_MOUNT_DIR detection in snap-confine (SD179)

Abstract

As a part of making snapd re-execution universal on all Linux distributions, we are working on removing compile-time assumptions from the C code, specifically from snap-confine. This document describes the required changes to snap-confine required to remove SNAP_MOUNT_DIR as a compile-time setting.

Rationale

At present we can only use snapd re-execution on distributions that are very similar to Ubuntu in the way they organize files and directories, most notably Debian. The C code has a number of compile-time decisions on which libraries to include, how to link with them, if a certain feature is enabled or disabled and certain directories used by snapd.

To achieve universal re-execution we technically need to remove compile-time decisions and turn them into runtime decisions, so that snap-confine or any other binary, compiled on Ubuntu works equally well on openSUSE, RHEL or Fedora which differ in some of the fundamental locations and expected features.

Specification

Runtime detection algorithm is provided below. The logic is safe to be called from another mount namespace and is able to handle /snap being a symbolic link (like it commonly is on Fedora or Arch)

# Shell-like pseudo-code, real C code is coded defensively and somewhat longer

if [ -l /proc/1/root/snap ]; then
	if [ "$(readlink /proc/1/root/snap)" != /var/lib/snapd/snap ]; then
		die "configuration: /snap is a symlink to something other than /var/lib/snapd/snap"
	fi
	# /snap is a symlink to /var/lib/snapd/snap - alternative mode
	SNAP_MOUNT_DIR=/var/lib/snapd/snap
elif [ ! -e /proc/1/root/snap ]; then
	# No /snap symlink or directory - alternative mode
	SNAP_MOUNT_DIR=/var/lib/snapd/snap
elif [ -d /proc/1/root/snap ]; then
	# /snap is a directory - canonical mode
	SNAP_MOUNT_DIR=/snap
else
	die "unsupported: /snap exists but is neither a directory nor a symlink"
fi
  • On startup snap-confine calls sc_probe_snap_mount_dir()
  • All use of SNAP_MOUNT_DIR is replaced by a call to sc_snap_mount_dir()
  • Compile-time string concatenation is replaced by sc_must_snprintf or g_build_filename (in tests)

Snap-confine’s apparmor profile is updated to allow both /snap and /var/lib/snapd/snap. This way the profile can stay static.

Further Information

Some changes to data files can follow the same pattern. The only exception is the static /etc/environment file addition which can add both locations, like the apparmor profile.

1 Like