apparmor: mediate AF_UNSPEC socket disconnects

aa_inet_connect_perm() returns success immediately for AF_UNSPEC
before checking the active AppArmor profile.  AF_UNSPEC is the socket
disconnect operation for TCP and UDP.  A process confined by a profile
containing deny network can therefore disconnect inherited sockets
even though ordinary socket creation and connect calls are denied.

console output:
fab5c58d6f/console-output.txt
reproduction kernel config:
b9192c97c9/kernel-config.txt
reproducer:
92c7dd098a/poc.c

Build the kernel from HEAD with the attached reproduction config, then
make a one-file initramfs.  The PoC mounts sysfs and securityfs
itself; DEVTMPFS_MOUNT supplies /dev/console.

    mkdir -p build rootfs
    cp kernel-config.txt build/.config
    make O=build olddefconfig
    make O=build -j"$(nproc)" bzImage
    cc -O2 -static -Wall -Wextra -o poc poc.c
    cp poc rootfs/poc
    (cd rootfs && find poc | cpio -o -H newc --owner=0:0) | gzip -9 > initramfs.cpio.gz
    timeout 900 qemu-system-x86_64 -kernel build/arch/x86/boot/bzImage \
        -initrd initramfs.cpio.gz -append "console=ttyS0 rdinit=/poc panic=-1 loglevel=7 lsm=apparmor security=apparmor apparmor=1" \
        -nographic -m 1024 -smp 1 -no-reboot 2>&1 | tee console.log

Under the deny-network profile, socket() and connect(AF_INET) returned
EACCES, but connect(fd, AF_UNSPEC) returned success and tore down the
inherited connection and listener.  Two fresh boots matched.  A
one-line control that routed AF_UNSPEC through aa_sk_perm returned
EACCES and kept both sockets alive.

Impact and prerequisites: A confined process that inherits a TCP/UDP
socket can bypass the profile's network mediation for disconnect and
disrupt that socket.  The finding does not permit socket creation,
bind, or arbitrary peer connections; no privilege escalation is
demonstrated.

Fixes: 89ac6aa752 ("apparmor: push inet mediation into profile callbacks, and improve auditing")
Signed-off-by: shaos <shawnq1@163.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
shaos 2026-10-20 00:12:56 +00:00 committed by John Johansen
parent a913281f60
commit 0497607465

View File

@ -425,7 +425,7 @@ int aa_inet_connect_perm(struct socket *sock, struct sockaddr *addr,
if (addrlen < offsetofend(struct sockaddr, sa_family))
return -EINVAL;
if (addr->sa_family == AF_UNSPEC)
return 0;
return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
/* do we need early bailout for !family ... */
return sk_has_perm2(sock->sk, OP_CONNECT, AA_MAY_CONNECT, profile, ad,