]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
apparmor: fix af_unix auditing to include all address information
authorJohn Johansen <john.johansen@canonical.com>
Sat, 14 Jun 2025 20:49:02 +0000 (13:49 -0700)
committerJohn Johansen <john.johansen@canonical.com>
Wed, 16 Jul 2025 05:39:43 +0000 (22:39 -0700)
The auditing of addresses currently doesn't include the source address
and mixes source and foreign/peer under the same audit name. Fix this
so source is always addr, and the foreign/peer is peer_addr.

Fixes: c05e705812d1 ("apparmor: add fine grained af_unix mediation")
Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/af_unix.c
security/apparmor/include/audit.h
security/apparmor/net.c

index 53ccf9becdf709da9ed6aba99d0851a4da959c1a..03d44fa19d12e9a29b877f324c79d8238621ef36 100644 (file)
@@ -584,8 +584,8 @@ static int unix_peer_perm(const struct cred *subj_cred,
        struct aa_profile *profile;
        DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
 
-       ad.net.addr = peer_addr;
-       ad.net.addrlen = peer_addrlen;
+       ad.net.peer.addr = peer_addr;
+       ad.net.peer.addrlen = peer_addrlen;
 
        return fn_for_each_confined(label, profile,
                        profile_peer_perm(profile, request, sk,
index 365bc67dd15090304400143f9795744a326f1680..1a71a94ea19c94c754093fdbf8da13bf51e3880d 100644 (file)
@@ -140,6 +140,10 @@ struct apparmor_audit_data {
                                        int type, protocol;
                                        void *addr;
                                        int addrlen;
+                                       struct {
+                                               void *addr;
+                                               int addrlen;
+                                       } peer;
                                } net;
                        };
                };
index e6f9e11eaa6a14e59020b0abc5bafce034fef38e..2da554cc3a35ac606662387ee8a25646139c7f8d 100644 (file)
@@ -99,10 +99,15 @@ static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
 {
        const struct unix_sock *u = unix_sk(sk);
 
-       if (u && u->addr)
-               audit_unix_addr(ab, str, u->addr->name, u->addr->len);
-       else
+       if (u && u->addr) {
+               int addrlen;
+               struct sockaddr_un *addr = aa_sunaddr(u, &addrlen);
+
+               audit_unix_addr(ab, str, addr, addrlen);
+       } else {
                audit_unix_addr(ab, str, NULL, 0);
+
+       }
 }
 
 /* audit callback for net specific fields */
@@ -137,17 +142,16 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
                }
        }
        if (ad->common.u.net->family == PF_UNIX) {
-               if ((ad->request & ~NET_PEER_MASK) && ad->net.addr)
+               if (ad->net.addr || !ad->common.u.net->sk)
                        audit_unix_addr(ab, "addr",
                                        unix_addr(ad->net.addr),
                                        ad->net.addrlen);
                else
                        audit_unix_sk_addr(ab, "addr", ad->common.u.net->sk);
                if (ad->request & NET_PEER_MASK) {
-                       if (ad->net.addr)
-                               audit_unix_addr(ab, "peer_addr",
-                                               unix_addr(ad->net.addr),
-                                               ad->net.addrlen);
+                       audit_unix_addr(ab, "peer_addr",
+                                       unix_addr(ad->net.peer.addr),
+                                       ad->net.peer.addrlen);
                }
        }
        if (ad->peer) {