View previous topic :: View next topic |
Author |
Message |
GrandeGrabois n00b
Joined: 16 Oct 2019 Posts: 47
|
Posted: Tue Nov 22, 2022 7:49 pm Post subject: appamor unix mediation not working as the man page says? |
|
|
Hello,
The apparmor userspace tools documentation states that:
Code: | $ man 5 apparmor.d
Unix socket rules
Apparmor supports fine grained mediation of unix domain abstract and anonymous sockets. Unix domain sockets with file system paths are mediated via file access. |
However, I've noticed after writing several profiles that program access to some unix sockets with filesystem paths was not being mediated by normal apparmor file rules. In particular, I observed programs using dbus ($XDG_RUNTIME_DIR/bus), pulseaudio ($XDG_RUNTIME_DIR/pulse/native) and wayland ($XDG_RUNTIME_DIR/wayland-?) sockets normally even after explicitly denying those paths.
So, to be sure, I ran a little test, with a pair of very simple programs using common libc socket functions (socket, bind, connect, send, recv, etc). The listener listens on $XDG_RUNTIME_DIR/testsock and the sender was used to send messages to this same socket.
I've created empty profiles for both programs and loaded then in complain mode. As far as filesystem access is involved, apparmor complained only of the creation of the file node itself (mknod on $XDG_RUNTIME_DIR/testsock). It did not acuse any attempts of reading or writing to this file while the transaction between the two programs was going on.
However, apparmor complained about lack of proper unix socket access rules for both programs (create, bind, receive and send).
So, it seems that apparmor mediation of unix sockets with filesystem paths is done by unix socket rules, not by regular filesystem access rules.
Either my understanting of the whole situation is incorrect - in which case I kindly ask you to point that out - or the man page is wrong... |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 4127 Location: Bavaria
|
Posted: Tue Nov 22, 2022 7:56 pm Post subject: |
|
|
Do you use abi <abi/3.0> or abi <kernel>
If you dont use an "abi"-statement then I have seen the same behaviour with networking (maybe we have a fallback into minimal without abi). abi is a must ! |
|
Back to top |
|
|
GrandeGrabois n00b
Joined: 16 Oct 2019 Posts: 47
|
Posted: Tue Nov 22, 2022 8:34 pm Post subject: |
|
|
pietinger wrote: | Do you use abi <abi/3.0> or abi <kernel>
If you dont use an "abi"-statement then I have seen the same behaviour with networking (maybe we have a fallback into minimal without abi). abi is a must ! |
Yes, I'm using abi/3.0 on all my profiles.
The complete profile for the tester programs I mentioned:
Code: | abi <abi/3.0>,
/home/grandeg/Progs/sender flags=(complain) {
/lib64/libc.so* rm,
/etc/ld.so.cache r,
} |
The listener program has the exact same profile, with the program name changed |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 4127 Location: Bavaria
|
Posted: Tue Nov 22, 2022 10:31 pm Post subject: |
|
|
What happens if you use abi <kernel>, instead (only for testing) ? |
|
Back to top |
|
|
GrandeGrabois n00b
Joined: 16 Oct 2019 Posts: 47
|
Posted: Wed Nov 23, 2022 12:51 am Post subject: |
|
|
pietinger wrote: | What happens if you use abi <kernel>, instead (only for testing) ? |
Same results.
This is very odd...
I'm using sys-apps/apparmor-3.0.3 and gentoo-sources-6.0.9.
The tester programs basically just call
Code: | // listener
sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)
bind(sockfd, (struct sockaddr *)&sock_path, sizeof(sock_path))
recv(sockfd, recv_buf, 2048, 0)
// sender
sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)
sendto(sockfd, argv[1], strlen(argv[1]), 0, (struct sockaddr *)&sock_path, sizeof(sock_path))
// sockpath is initialized in both cases as
struct sockaddr_un sock_path = { .sun_family = AF_UNIX, .sun_path = "/run/user/1000/testsock\0" }
|
Both profiles are almost identical:
Code: | abi <kernel>,
/home/grandeg/Progs/listener flags=(complain) {
/lib64/libc.so* rm,
/etc/ld.so.cache r,
}
|
When running the programs and sending one message (the listener just prints what it receives), I get the following from apparmor:
Code: | AVC apparmor="ALLOWED" operation="create" profile="/home/grandeg/Progs/listener" pid=1209 comm="listener" family="unix" sock_type="dgram", protocol=0 requested_mask="create" denied_mask="create"
AVC apparmor="ALLOWED" operation="bind" profile="/home/grandeg/Progs/listener" pid=1209 comm="listener" family="unix" sock_type="dgram", protocol=0 requested_mask="bind" denied_mask="bind"
AVC apparmor="ALLOWED" operation="mknod" profile="/home/grandeg/Progs/listener" name="/run/user/1000/testsock" pid=1209 comm="listener" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
AVC apparmor="ALLOWED" operation="recvmsg" profile="/home/grandeg/Progs/listener" pid=1209 comm="listener" family="unix" sock_type="dgram", protocol=0 requested_mask="receive" denied_mask="receive"
AVC apparmor="ALLOWED" operation="create" profile="/home/grandeg/Progs/sender" pid=1304 comm="sender" family="unix" sock_type="dgram", protocol=0 requested_mask="create" denied_mask="create"
AVC apparmor="ALLOWED" operation="sendmsg" profile="/home/grandeg/Progs/sender" pid=1304 comm="sender" family="unix" sock_type="dgram", protocol=0 requested_mask="send" denied_mask="send"
|
So it seems that unix socket access is being mediated by socket rules, even though the socket is a filesystem object. Apparmor just complains about the file being created.
Is there something wrong here? |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 4127 Location: Bavaria
|
Posted: Wed Nov 23, 2022 2:28 am Post subject: |
|
|
GrandeGrabois,
first let me say sorry for not understanding your question in the first run. First I thought AA allows networking without explicit rule. I hope I understand it now ... and I think (=not knowing for sure) it is the same as with DBUS =>
It is not implemented in our kernel.
You surely know AA needs kernel hooks for checking its rules. I know other distributions have/use kernel patches to extend needed hooks, so I think the informations in the manpage are not wrong (you will see there also information about DBUS which is clearly NOT in our kernel); they are for AA with "ALL" kernel patches ... (which are not accepted by kernel developers for vanilla kernel at the moment; our gentoo kernel is almost mainly vanilla).
For my understanding AA is still in development ... as you can see also in its documentation:
Quote: | The implementation of AppArmor network rules is broken into three
parts, the mediation of sockets, the labeling of packets, and the
mediation of packets. When AppArmor compiles policy it splits network
rules into these three separate parts.
The mediation of sockets, and packets is handled entirely within the
AppArmor mediation engine, the labeling of packets is however handled
by linux's iptables using secmark and connsecmark.
By default AppArmor will create an iptable with the appropriate
labeling for AppArmor policy from the set of system network rules, so
that policy does not need to be split between iptables and AppArmor
profiles. However there is nothing stopping a user from handling
labeling in iptables.
??? need to let apparmor know that the reserved labels exist ??? need
to write rules that use the labels, most likely ipc rules |
(from: https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference )
Please dont ask me for "AppArmor mediation engine" ... |
|
Back to top |
|
|
GrandeGrabois n00b
Joined: 16 Oct 2019 Posts: 47
|
Posted: Wed Nov 23, 2022 7:49 pm Post subject: |
|
|
pietinger,
That seems to be the case. Documentation is clearly writen with distributions that ship a fully patched apparmor (kernel-side) in mind. If I remeber correctly, we are waiting for dbus mediation to be merged in the mainline for at least a couple of years now...
Since right now pathname unix socket mediation is done by unix rules and not by regular file access rules, I was willing to see how much control I could get on this type of access with the unix rules. On the current gentoo kernel.
So I added this rule to the profiles and apparmor still complains about socket access.
If I add then it does not complain anymore.
So, thats great. Working as described. Because I'm really using sockets of type DGRAM in my testing.
Bearing in mind that "unix type=stream," is the same as "unix stream" or "network unix stream". From what I gather, this is the "coarse grained" mediation provided by network rules.
Let's see if we have fine grained mediation.
Code: | unix addr=/run/user/1000/testsock |
The profile does not compile (parser error: invalid value for addr=). Thats because fine grained socket rules are supposed to mediate only abstract and anonymous sockets.
So I add
Code: | unix addr=@doesnotexist, |
And now the profile is OK, but apparmor does not complain anymore about any access to the socket (which is still in /run/user/1000/testsock). So it seems that the fine grained rule set above was collapsed to allow all unix socket access.
This is explained in the man page:
Code: | Fine grained mediation rules however can not be losslessly converted back to the coarse grained network rule; e.g.
unix bind addr=@example,
Has no exact match under coarse grained network rules, the closest match is the much wider permission rule of
network unix, |
So I've modified the tester programs to use abstract sockets
Code: | struct sockaddr_un sock_path = { .sun_family = AF_UNIX, .sun_path = "\0/run/user/1000/testsock" |
And still, none of the fine grained unix socket rules work. e.g. if I set this rule
Code: | unix (create, send), |
On the listener program, it still does not complain about the bind and receive actions. So it is still colapsing to "unix," (allow all unix socket acces).
To sum it all up, it seems:
1) mainline is still missing support for fine grained mediation of unix sockets.
2) mediation of pathname (as well as abstract) unix sockets is done with coarse grained network rules, i. e. by socket type.
Now, frankly, the first point is just a feature that hasn't been merged yet. But the second one might just be unintended behavior...
Anyway, sorry if you already knew all of that. But it was a pretty big finding to me and I thought I should share... |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 4127 Location: Bavaria
|
Posted: Wed Nov 23, 2022 9:34 pm Post subject: |
|
|
GrandeGrabois wrote: | Anyway, sorry if you already knew all of that. But it was a pretty big finding to me and I thought I should share... |
Please dont say sorry. I am not an AA expert ... and I am very thankful for your findings and I love to learn new things. So, thank you very much !
I dont try to do so fine grained rules. My method is very simple (and maybe not so secure): I dont allow applications with network traffic access to my data; apps with access to my /home dont have any access to network. Of course my mail program has acccess to network (*) AND its own data files; and of course my browser is allowed to read/write its own config files and ~/Downloads/*
*) What AA cant do must do my firewall: So, kmail can only connect to my mail provider ... if kmail would try to "phone home" via https I would see it in the logs of my proxy ... filtering outgoing traffic is important. |
|
Back to top |
|
|
GrandeGrabois n00b
Joined: 16 Oct 2019 Posts: 47
|
Posted: Wed Nov 23, 2022 11:21 pm Post subject: |
|
|
pietinger wrote: | Please dont say sorry. I am not an AA expert ... and I am very thankful for your findings and I love to learn new things. So, thank you very much ! |
Wow, I'm really happy for that. Glad to be of any help!!! I'm also messing with this stuff mainly for the learning experience, its not like I have any concrete need to implement such restrictions.
Although, I do have foot (the wayland terminal emulator) running as a server. foot listens on a pathname socket for footclient connections. The clients just draw the windows and collect the input, sending then to the server (via the socket) that runs the commands.
So this is an example of a socket I would like to restrict access to. If an application can write to this socket, then it can run anything unrestricted. Now, pretty much every GUI applicantion needs access to the wayland/xorg socket. So it turns out I have no way (with apparmor) to restrict an application from accessing only the display (or only the soundserver, or only the dbus) socket, even though they are filesystem objects.
I'm actually not very worried about this, but it is what set me in this course in the first place. It makes me wonder why there is so much functionality from apparmor not merged in the mainline kernels. Maybe it lost some of its appeal, since namespaces are the main technology for application restriction nowadays? |
|
Back to top |
|
|
pietinger Moderator
Joined: 17 Oct 2006 Posts: 4127 Location: Bavaria
|
Posted: Thu Nov 24, 2022 1:07 pm Post subject: |
|
|
GrandeGrabois wrote: | [...] It makes me wonder why there is so much functionality from apparmor not merged in the mainline kernels. Maybe it lost some of its appeal, since namespaces are the main technology for application restriction nowadays? |
You surely know you cant have SELinux AND AA ... so, maybe (= I dont know) kernel development is waiting for another solution before extending apparmor: stackable LSM => https://lwn.net/Articles/912775/
As long as Ubuntu, Debian and SuSe work with AA I dont think AA will die. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|