cmd: add non-stub implementation of snap-update-ns #2718

Closed
wants to merge 2 commits into
from

Conversation

Projects
None yet
3 participants
Contributor

zyga commented Jan 25, 2017

This patch adds an almost full implementation of snap-update-ns.

This new executable includes a simple utility module for working with
mount entries (e.g. /etc/fstab) that is based on the C library for the
hard part (parsing).

The missing bits are:

  • there's no locking; I will tweak ns-support to expose that better
  • snapd doesn't generate the snap.$SNAP_NAME.fstab file yet
  • snapd doesn't call snap-update-ns yet (easy)
  • snap-update-ns cannot yet realize that a mount already happened

The last missing bit requires some more explanation. The tool already
inspect existing mount points but due to the way bind mounts are exposed
in the kernel it is non-trivial to realize that a given place is a bind
mount (even if we have all the information in front of us).

One notable unfortunate fact is that snap-update-ns cannot take advantage
of valgrind for debugging:

--41370-- WARNING: unhandled amd64-linux syscall: 308
--41370-- You may be able to write your own handler.
--41370-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--41370-- Nevertheless we consider this a bug. Please report
--41370-- it at http://valgrind.org/support/bug_reports.html.
cannot re-associate with mount namespace of snap unix-domain-client: Function not implemented

Signed-off-by: Zygmunt Krynicki zygmunt.krynicki@canonical.com

cmd: add non-stub implementation of snap-update-ns
This patch adds an almost full implementation of snap-update-ns.

This new executable includes a simple utility module for working with
mount entries (e.g. /etc/fstab) that is based on the C library for the
hard part (parsing).

The missing bits are:
 - there's no locking; I will tweak ns-support to expose that better
 - snapd doesn't generate the snap.$SNAP_NAME.fstab file yet
 - snapd doesn't call snap-update-ns yet (easy)
 - snap-update-ns cannot yet realize that a mount already happened

The last missing bit requires some more explanation. The tool already
inspect existing mount points but due to the way bind mounts are exposed
in the kernel it is non-trivial to realize that a given place is a bind
mount (even if we have all the information in front of us).

One notable unfortunate fact is that snap-update-ns cannot take advantage
of valgrind for debugging:

--41370-- WARNING: unhandled amd64-linux syscall: 308
--41370-- You may be able to write your own handler.
--41370-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--41370-- Nevertheless we consider this a bug.  Please report
--41370-- it at http://valgrind.org/support/bug_reports.html.
cannot re-associate with mount namespace of snap unix-domain-client: Function not implemented

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>

@zyga zyga added this to the 2.23 milestone Jan 26, 2017

This is just a high-level look at the PR per @zyga's request and not a deep review. This appears to adhere to the spec except for the TODO part for the wiki (I summarized my understanding there).

While I think for a design perspective, this is fine to proceed, @tyhicks and I agree that https://bugs.launchpad.net/apparmor/+bug/1656121 needs to be worked out before the security team spends time on a deep review of this PR, as the outcome of that bug might impact the implementation and full review.

+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ printf("Usage: snap-alter-ns SNAP-NAME");
@jdstrand

jdstrand Jan 26, 2017

Contributor

s/snap-alter-ns/snap-update-ns/ here and elsewhere.

@zyga

zyga Jan 27, 2017

Contributor

Yep, will do.

+ return 0;
+ }
+ // TODO: correct the wiki, we don't quit if something is not present as
+ // this is a valid case as well (e.g. a profile gets removed).
@jdstrand

jdstrand Jan 26, 2017

Contributor

The use cases are:

  • neither exists: nothing to do
  • current exists but desired does not: unmount everything and remove current (profile removal)
  • current does not exist, but desired does: mount everything and create current (first run after profile add)
  • both exist: mount/umount as necessary and update current (subsequent updates not including profile removal)
@zyga

zyga Jan 27, 2017

Contributor
  • neither exist == both are empty => nothing to do (check, agreed)
  • current exists but desired does not == treat desired as empty => will unmount everything in current (check, agreed)
  • current does not exist but desired does == treat current as empty => will mount everything in desired (check, agreed with the exception that I plan to make snap-confine write current on successful startup)
  • both exists: unmount those that are not in desired but are in current, mount those that are in desired but are not in current; (check, agreed)

I think we are in agreement here.

+ }
+ }
+ if (num_skipped > 0) {
+ debug("Mount namespace of snap %s has not been fully altered.",
@jdstrand

jdstrand Jan 26, 2017

Contributor

s/altered/updated/ here and elsewhere

@zyga

zyga Jan 27, 2017

Contributor

Yep, will do.

cmd/snap-update-ns/snap-update-ns.c
+ struct mountinfo __attribute__ ((cleanup(cleanup_mountinfo))) * mi =
+ NULL;
+ const char *mnt_dir;
+ mi = parse_mountinfo(NULL);
@jdstrand

jdstrand Jan 26, 2017

Contributor

Need to check if mi is NULL here.

@zyga

zyga Jan 27, 2017

Contributor

Good catch, will do

cmd/snap-update-ns/snap-update-ns.c
+ mountinfo_entry_parent_id
+ (parent_mi_entry));
+ }
+ return false;
@jdstrand

jdstrand Jan 26, 2017

Contributor

While there is a lot going on here to deal with debug info, it's good that you performed this "mounting over mountpoints" check.

@zyga

zyga Jan 27, 2017

Contributor

I'll trim down the debug info if required (though we don't show it unless you ask for it). I'd like to return a simple and understandable error message when we reject the over-mount.

Contributor

zyga commented Jan 27, 2017

I'll address the review feedbackc and focus on investigating the kernel issue.

Merge branch 'master' of github.com:snapcore/snapd into snap-update-n…
…s-part1

I adapted the code to recent changes to string-utils and mountinfo in
master. Nothing major, just some extra sc_ up front.
Contributor

niemeyer commented Feb 14, 2017

For the record, @zyga is using this as a master sketch for proposing other PRs. Closing it as it'll eventually be all done in smaller pieces, which is much better. Thanks for that @zyga.

@niemeyer niemeyer closed this Feb 14, 2017

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