The above analysis is true for SSH, but, I realise it's different for
the PTY passed in by lxc exec.

So my analysis is true maybe, but I am going to move this SSH fix over
to Bug #1667016 so this bug can stay open for the general PTY/buffering
issue.

There is a gap in my explanation of: It's not clear to me why this
doesn't also happen outside of a container.

Of note I found that the error I get initially suggests it couldn't resolve the 
path of the FD, which seems probably to be /dev/pts:
[ 9119.221342] audit: type=1400 audit(1666766810.741:452): apparmor="DENIED" 
operation="getattr" info="Failed name lookup - disconnected path" error=-13 
namespace="root//lxd-juju-5062b7-2-lxd-3_<var-snap-lxd-common-lxd>" 
profile="/usr/sbin/tcpdump" name="apparmor/.null" pid=257511 comm="tcpdump" 
requested_mask="r" denied_mask="r" fsuid=1000108 ouid=0

However the same fix makes this go away. Is apparmor or this error
message failing to identify the path for some reason because it has no
permission to stat it in that apparmor context or something? Also is
"/dev r" a faulty permission?


It's notable that after I reload the apparmor profile, and sometimes
randomly, the current terminal session has this issue go away - it seems
it can resolve the path for a while. e.g. if i add and then remove the
consoles abstraction, it suddenly works inside that session. But if I
logout/login it breaks again.

I'm a bit lost here :)

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to apparmor in Ubuntu.
https://bugs.launchpad.net/bugs/1641236

Title:
  Confined processes inside container cannot fully access host pty
  device passed in by lxc exec

Status in apparmor package in Ubuntu:
  Confirmed
Status in lxd package in Ubuntu:
  Invalid
Status in tcpdump package in Ubuntu:
  Confirmed

Bug description:
  Now that AppArmor policy namespaces and profile stacking is in place,
  I noticed odd stdout buffering behavior when running confined
  processes via lxc exec. Much more data stdout data is buffered before
  getting flushed when the program is confined by an AppArmor profile
  inside of the container.

  I see that lxd is calling openpty(3) in the host environment, using
  the returned fd as stdout, and then executing the command inside of
  the container. This results in an AppArmor denial because the file
  descriptor returned by openpty(3) originates outside of the namespace
  used by the container.

  The denial is likely from glibc calling fstat(), from inside the
  container, on the file descriptor associated with stdout to make a
  decision on how much buffering to use. The fstat() is denied by
  AppArmor and glibc ends up handling the buffering differently than it
  would if the fstat() would have been successful.

  Steps to reproduce (using an up-to-date 16.04 amd64 VM):

  Create a 16.04 container
  $ lxc launch ubuntu-daily:16.04 x

  Run tcpdump in one terminal and generate traffic in another terminal (wget 
google.com)
  $ lxc exec x -- tcpdump -i eth0
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
  <Packet dump>
  47 packets captured
  48 packets received by filter
  1 packet dropped by kernel
  <ctrl-c>

  Note that everything above <Packet dump> was printed immediately
  because it was printed to stderr. <Packet dump>, which is printed to
  stdout, was not printed until you pressed ctrl-c and the buffers were
  flushed thanks to the program terminating. Also, this AppArmor denial
  shows up in the logs:

  audit: type=1400 audit(1478902710.025:440): apparmor="DENIED"
  operation="getattr" info="Failed name lookup - disconnected path"
  error=-13 namespace="root//lxd-x_<var-lib-lxd>"
  profile="/usr/sbin/tcpdump" name="dev/pts/12" pid=15530 comm="tcpdump"
  requested_mask="r" denied_mask="r" fsuid=165536 ouid=165536

  Now run tcpdump unconfined and take note that <Packet dump> is printed 
immediately, before you terminate tcpdump. Also, there are no AppArmor denials.
  $ lxc exec x -- aa-exec -p unconfined -- tcpdump -i eth0
  ...

  Now run tcpdump confined but in lxc exec's non-interactive mode and note that 
<Package dump> is printed immediately and no AppArmor denials are present. 
(Looking at the lxd code in lxd/container_exec.go, openpty(3) is only called in 
interactive mode)
  $ lxc exec x --mode=non-interactive -- tcpdump -i eth0
  ...

  Applications that manually call fflush(stdout) are not affected by
  this as manually flushing stdout works fine. The problem seems to be
  caused by glibc not being able to fstat() the /dev/pts/12 fd from the
  host's namespace.

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


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

Reply via email to