Skip to content

Netlink socket attack surface

AF_NETLINK, yüzlerce kernel subsystem'iyle userspace arasında mesaj taşıyan geniş bir ring0 arayüzü; unprivileged veya namespaced kullanıcıdan erişilebilir olması onu sürekli tekrar eden bir LPE bug kaynağı yapar.

Mechanism

Note

Netlink, socket tabanlı bir message-passing kanalıdır: userspace sendmsg()/recvmsg() ile TLV (type-length-value) nlattr attribute'ları taşıyan mesajlar gönderir, kernel de ilgili subsystem'in handler'ına dispatch eder. Yapısal kırılganlık üç yerden gelir — (1) her family kendi attribute-parsing ve policy-validation kodunu taşır, yani yüzlerce ayrı ayrıştırıcı; (2) her genl family'nin per-family handler'ı ayrı bir kod yüzeyidir (rtnetlink, nftables, taskstats, nl80211, ipvs, xfrm...); (3) netlink_sock object'inin kendi refcount ömrü, socket buffer attach/detach ve async completion path'lerinde yanlış yönetildiğinde UAF üretir. Kritik nokta: çoğu family'yi açmak capability gerektirmez, gereken yerlerde de CAP_NET_ADMIN bir unprivileged user namespace içinde elde edilebilir. Bu yüzden netlink, default bir Linux'ta unprivileged koda açık en geniş kernel API yüzeyidir.

Walkthrough

Bir netlink socket açmak ve bir family'ye mesaj sürmek tek başına privilege gerektirmez:

/* NETLINK_ROUTE / rtnetlink; nftables için NETLINK_NETFILTER, genl için NETLINK_GENERIC */
int s = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
bind(s, (struct sockaddr *)&sa, sizeof(sa));
/* nlmsghdr + nlattr TLV zinciri kur, sonra sendmsg() ile kernel handler'ına dispatch et */
sendmsg(s, &msg, 0);

Namespaced erişim tipik olarak şöyle başlar — yeni bir user namespace, içeride sahte CAP_NET_ADMIN, sonra normalde ayrıcalıklı olan family'ye ulaşma:

unshare(CLONE_NEWUSER | CLONE_NEWNET);   /* userns içinde CAP_NET_ADMIN kazanılır */
/* artık nftables/rtnetlink handler'ları unprivileged UID'den erişilebilir */

Bu yüzey üzerinden erişilen, doğrulanmış temsili bug sınıfları:

  • Attribute-parsing / heap corruptionCVE-2021-27365 (iSCSI netlink'te sysfs attribute uzunluk kontrolü eksikliği, heap OOB) ve CVE-2023-6931 (genl üzerinden erişilebilen perf_event integer overflow) gibi, TLV/uzunluk doğrulamasının kaçtığı hatalar.
  • Per-family handler / policy bypassCVE-2022-47929 (nftables netlink policy NULL-deref) ve CVE-2024-26924 (nftables pipapo set garbage-collection UAF); ikisi de bir netlink socket'ten gelen mesaj dizisiyle tetiklenir ve unprivileged userns'ten erişilebilir.
  • netlink_sock refcount / UAFCVE-2017-11176: mq_notify(), bir netlink socket fd'sine skb attach ederken retry path'inde sock pointer'ını NULL'a resetlemez; netlink_attachskb() bir kez sock_put() yapar, exit path'i netlink_detachskb() ile bir kez daha yapar. Başka bir thread'den socket'i retry penceresinde close() etmek refcount'u sıfıra düşürüp object'i free eder, sonraki netlink_detachskb() dangling pointer üzerinde çalışır — ders kitabı bir UAF. (Bkz. mq-notify-netlink-sock-double-sock-put-uaf.)

Warning

Netlink handler'larının çoğu heap üzerinde sk_buff ve nlattr buffer'ları allocate eder; bir UAF/OOB primitive'i genellikle sk-buff-spray veya sendmsg-ancillary-data-spray gibi heap grooming teknikleriyle birleştirilerek control edilebilir bir overwrite'a çevrilir. Yani tek bir family bug'ı, geniş bir exploitation ekosistemine bağlanır.

Detection

  • Güvenilmeyen veya container context'lerinden beklenmedik socket(AF_NETLINK, ...) oluşturulmasını flag'le; özellikle bir uygulama profilinde normalde görülmeyen NETLINK_NETFILTER (nftables) veya NETLINK_GENERIC family'lerini.
  • unshare(CLONE_NEWUSER) / CLONE_NEWNET çağrılarının hemen ardından netlink socket açılması yaygın bir LPE ön-hazırlık pattern'idir — bu ikiliyi telemetride korele et (auditd syscall kuralları, Falco unexpected netlink socket benzeri kurallar).
  • nftables/rtnetlink üzerinden anormal yüksek hacimli veya hızlı transaction abort/replay dizileri (garbage-collection ve generation-mask bug'larının tetikleme imzası) bir anomali sinyalidir.
  • KASAN/KFENCE'li kernel'lerde netlink/nft/sk_buff slab'lerinde use-after-free ve slab-out-of-bounds splat'ları doğrudan bu yüzeydeki exploitation denemelerine işaret eder.

Mitigation

  • Unprivileged user namespace'leri kısıtla: sysctl kernel.unprivileged_userns_clone=0 (veya user.max_user_namespaces=0), namespaced CAP_NET_ADMIN yolunu kapatarak birçok ayrıcalıklı family'ye erişimi keser.
  • Netlink'e ihtiyaç duymayan workload'larda socket(AF_NETLINK, ...)'i bir seccomp filter ile blokla; ihtiyaç varsa ilgili family'leri AppArmor/SELinux ile daralt.
  • Gereksiz capability'leri düşür (CAP_NET_ADMIN başta olmak üzere); container'ları bu capability olmadan çalıştır.
  • Kernel'leri patch'li tut: yukarıdaki doğrulanmış bug'lar ilgili stable release'lerinde düzeltilmiştir. Mümkünse CONFIG_NF_TABLES gibi ihtiyaç duyulmayan family'leri derleme dışı bırak.

References