** Changed in: linux (Ubuntu Yakkety)
       Status: New => Fix Committed

** Changed in: linux (Ubuntu Xenial)
       Status: New => Fix Committed

-- 
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1656121

Title:
  unexpected errno=13 and disconnected path when trying to open
  /proc/1/ns/mnt from a unshared mount namespace

Status in AppArmor:
  Confirmed
Status in linux package in Ubuntu:
  Incomplete
Status in linux source package in Xenial:
  Fix Committed
Status in linux source package in Yakkety:
  Fix Committed

Bug description:
  This bug is based on a discussion with jjohansen on IRC.

  While working on a feature for snapd
  (https://github.com/snapcore/snapd/pull/2624) we came across an
  unexpected EACCES that only seems to happen when apparmor is in the
  loop.

  The kernel log shows something interesting. The full log is available
  here: http://paste.ubuntu.com/23789099/

  Jan 12 23:16:43 autopkgtest kernel: [  498.616822] audit: type=1400
  audit(1484259403.009:67): apparmor="ALLOWED" operation="open"
  info="Failed name lookup - disconnected path" error=-13 profile="snap
  .test-snapd-tools.cmd//null-/usr/bin/snap//null-/usr/lib/snapd/snap-
  confine" name="" pid=25299 comm="snap-confine" requested_mask="r"
  denied_mask="r" fsuid=0 ouid=0

  The code that triggers this is reproduced below (also visible here
  https://github.com/snapcore/snapd/pull/2624/files)

  +void sc_reassociate_with_pid1_mount_ns()
   +{
   +    int init_mnt_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1;
   +    int self_mnt_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1;
   +
   +    debug("checking if the current process shares mount namespace"
   +          "with the init process");
   +
   +    init_mnt_fd = open("/proc/1/ns/mnt",
   +                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_PATH);
   +    if (init_mnt_fd < 0) {
   +            die("cannot open mount namespace of the init process (O_PATH)");
   +    }
   +    self_mnt_fd = open("/proc/self/ns/mnt",
   +                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_PATH);
   +    if (self_mnt_fd < 0) {
   +            die("cannot open mount namespace of the current process 
(O_PATH)");
   +    }
   +    char init_buf[128], self_buf[128];
   +    memset(init_buf, 0, sizeof init_buf);
   +    if (readlinkat(init_mnt_fd, "", init_buf, sizeof init_buf) < 0) {
   +            die("cannot perform readlinkat() on the mount namespace file "
   +                "descriptor of the init process");
   +    }
   +    memset(self_buf, 0, sizeof self_buf);
   +    if (readlinkat(self_mnt_fd, "", self_buf, sizeof self_buf) < 0) {
   +            die("cannot perform readlinkat() on the mount namespace file "
   +                "descriptor of the current process");
   +    }
   +    if (memcmp(init_buf, self_buf, sizeof init_buf) != 0) {
   +            debug("the current process does not share mount namespace with "
   +                  "the init process, re-association required");
   +            // NOTE: we cannot use O_NOFOLLOW here because that file will 
always be a
   +            // symbolic link. We actually want to open it this way.
   +            int init_mnt_fd_real
   +                __attribute__ ((cleanup(sc_cleanup_close))) = -1;
   +            init_mnt_fd_real = open("/proc/1/ns/mnt", O_RDONLY | O_CLOEXEC);
   +            if (init_mnt_fd_real < 0) {
   +                    die("cannot open mount namespace of the init process");
   +            }
   +            if (setns(init_mnt_fd_real, CLONE_NEWNS) < 0) {
   +                    die("cannot re-associate the mount namespace with the 
init process");
   +            }
   +    } else {
   +            debug("re-associating is not required");
   +    }
   +}

  The specific part that causes the error is:

   +              init_mnt_fd_real = open("/proc/1/ns/mnt", O_RDONLY |
  O_CLOEXEC);

  The call to open returns -1 and errno set to 13 (EACCES) despite using
  attach_disconnected.

  The code in question is executed from a seguid root executable that
  runs under a complain-mode profile (it is started from a process that
  is already confined with such a profile). All of the profiles are
  using attach_disconnected.

  I can reproduce this issue each time by running:

  spread -debug -v qemu:ubuntu-16.04-64:tests/regression/lp-1644439

  Against the code in this pull request:

  https://github.com/snapcore/snapd/pull/2624

  Which is git://github.com/zyga/snapd in the "reassociate-fix" branch

  Appropriate qemu images can be made using instructions from:

  https://github.com/zyga/spread-qemu-images

  I'm also happy to try any test kernels as I can easily run those.

To manage notifications about this bug go to:
https://bugs.launchpad.net/apparmor/+bug/1656121/+subscriptions

-- 
Mailing list: https://launchpad.net/~kernel-packages
Post to     : kernel-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kernel-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to