[pkg-apparmor] tcpdump profile breaks default output buffering mode when tcpdump is executed in non-default network name spaces
Garri Djavadyan
g.djavadyan at gmail.com
Sun Sep 1 13:10:10 BST 2024
Hi Debian AppArmor Team,
May I ask your advice on how to tackle the following AppArmor issue in
a fully updated Debian 12 system without losing the benefit of
confining tcpdump?
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-----
So I guess, even though the file 'dev/pts/10' in both filesystem
contexts actually represents the same terminal, AppArmor, most
probably, does not know that; thus it blocks the request.
I wonder if my conclusions make sense, and if so, do you think AppArmor
can be extended to support such cases? If AppArmor is already capable
of handling such cases, do you think the default Debian profile for
'tcpdump' can be extended to tackle the problem without enabling the
debug-only flag "attach_disconnected"?
Thank you in advance!
Regards,
Garri
[1] https://lists.ubuntu.com/archives/apparmor/2018-July/011718.html
More information about the pkg-apparmor-team
mailing list