Package: tcpdump
Version: 4.99.3-1
Recently, I noticed that 'tcpdump' cannot use per-line buffering by
default when it is executed in non-default network namespaces. For
example, when it is executed in the following ways:
-----BEGIN CLI-----
$ sudo ip netns exec net0 tcpdump -ni veth0
# or
$ sudo ip netns exec net0 bash
# tcpdump -ni veth0
-----END CLI-----
When the first packet arrives, 'tcpdump' tries to check if the standard
output is a terminal, and while doing this, it tries to read the
attributes of the related pts device. However, AppArmor blocks such
calls:
Aug 31 14:41:24 localhost audit[6350]: AVC apparmor="DENIED"
operation="getattr" class="file" info="Failed name lookup -
disconnected path" error=-13 profile="tcpdump" name="dev/pts/10"
pid=6350 comm="tcpdump" requested_mask="r" denied_mask="r" fsuid=102
ouid=0
I tried to extend the default profile for tcpdump by allowing access to
pts devices:
-----BEGIN CLI-----
# cat /etc/apparmor.d/local/usr.bin.tcpdump
/dev/pts/[0-9]* r,
# apparmor_parser -Q --debug /etc/apparmor.d/usr.bin.tcpdump | grep pts
Mode: complain
Mode: r:r Name: (/dev/pts/[0-9]*)
-----END CLI-----
... but it did not work.
Also, it does not help if I move the profile into the complain mode;
the audit log shows that the call is ALLOWED, but in fact, AppArmor
still blocks the call (checked with strace):
-----BEGIN CLI-----
Aug 31 14:53:05 localhost audit[6366]: AVC apparmor="ALLOWED"
operation="getattr" class="file" info="Failed name lookup -
disconnected path" error=-13 profile="tcpdump" name="dev/pts/10"
pid=6366 comm="tcpdump" requested_mask="r" denied_mask="r" fsuid=102
ouid=0
# ps -efZ | grep tcpdump | grep -v grep
tcpdump (complain) tcpdump 6391 6337 0 14:58
pts/10 00:00:00 tcpdump -ni veth0 icmp
# aa-status
apparmor module is loaded.
7 profiles are loaded.
6 profiles are in enforce mode.
/usr/bin/man
lsb_release
man_filter
man_groff
nvidia_modprobe
nvidia_modprobe//kmod
1 profiles are in complain mode.
tcpdump
0 profiles are in kill mode.
0 profiles are in unconfined mode.
1 processes have profiles defined.
0 processes are in enforce mode.
1 processes are in complain mode.
/usr/bin/tcpdump (6391) tcpdump
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.
# strace output showing that the access is still blocked
newfstatat(1, "", 0x7ffe927d5be0, AT_EMPTY_PATH) = -1 EACCES
(Permission denied)
-----END CLI-----
Finally, I loaded the latest stable kernel 6.10.6 from the backports,
but it did not help either:
-----BEGIN CLI-----
# uname -a
Linux localhost 6.10.6+bpo-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.10.6-
1~bpo12+1 (2024-08-26) x86_64 GNU/Linux
-----END CLI-----
I can only overcome the issue when I:
1. unload the 'tcpdump' profile completely;
2. modify the 'tcpdump' profile with the debug flag
"attach_disconnected"; or
3. execute a second 'sshd' instance in the non-default network
namespace, in which I run 'tcpdump', and ssh to that context directly
to execute 'tcpdump'.
After reading this thread [1] about name space specifics and some other
threads about the "Failed name lookup - disconnected path" error, I
suspect that AppArmor blocks the aforementioned tcpdump's call because
sshd, running in the default NS context, and tcpdump, running in the
non-default NS context, also have '/dev/pts' mount in different FS
contexts. For example:
-----BEGIN CLI-----
# grep pts /proc/`ps -ef | grep tcpdump | grep -v grep | awk '{print
$2}'`/mountinfo
437 436 0:23 / /dev/pts rw,nosuid,noexec,relatime master:3 - devpts
devpts rw,gid=5,mode=620,ptmxmode=000
# grep pts /proc/1/mountinfo
26 25 0:23 / /dev/pts rw,nosuid,noexec,relatime shared:3 - devpts
devpts rw,gid=5,mode=620,ptmxmode=000
-----END CLI-----
I also posted the description of the problem to the AppArmor mailing
list [2] recently.
Thank you.
Garri
[1] https://lists.ubuntu.com/archives/apparmor/2018-July/011718.html
[2]
https://alioth-lists.debian.net/pipermail/pkg-apparmor-team/2024-September/004204.html