net/sched sch_hfsc UAF (CVE-2023-4623)¶
HFSC qdisc'inde bir use-after-free: link-sharing curve'ü olan bir class, hiç curve'ü olmayan bir parent altında oluşturulduğunda,
init_vf()parent'ı vt-tree'ye insert eder amaupdate_vf()onu hiç remove etmez ve dangling bir pointer bırakır — bir unprivileged local privilege-escalation bug'ı.
Mechanism¶
Note
HFSC (Hierarchical Fair Service Curve), link-sharing service curve'ü
(HFSC_FSC flag'i) olan class'ları per-parent bir "virtual-time tree"
(vt-tree) içinde izler, böylece scheduler service edilecek bir sonraki
class'ı seçebilir. Lifecycle invariant'ı simetridir: bir class'ın
parent'ının vt-tree'sine her vttree_insert()'i, class deactivate olduğunda
bir vttree_remove() ile dengelenmelidir. Bug bu simetriyi bozar. Bir
link-sharing curve'ü olan bir class (HFSC_FSC set), link-sharing
curve'ü olmayan bir parent'a attach edilirse, init_vf() yine parent
üzerinde vttree_insert() çağırır, ama karşılık gelen vttree_remove()
update_vf()'te atlanır, çünkü removal path parent'ın curve flag'lerine
gate'lenmiştir. Dolayısıyla parent'ın vt-tree'si free edilebilecek bir class'a
bir pointer tutar, dangling bir reference ve scheduler daha sonra tree'yi
dolaştığında bir use-after-free verir.
Walkthrough¶
HFSC qdisc'i bir unprivileged user+net namespace içinden (o netns üzerinde
CAP_NET_ADMIN) yapılandırılabilir, yani gerçek bir privilege gerekmez:
Asimetrik hiyerarşiyi kurun: link-sharing (ls/sc) curve'ü olmayan bir
root/parent HFSC class, sonra bir curve'ü olan bir child class. tc,
service-curve knob'larını doğrudan expose eder:
# root HFSC qdisc
tc qdisc add dev lo root handle 1: hfsc default 1
# parent class with NO link-sharing curve (e.g. only upper-limit / real-time)
tc class add dev lo parent 1: classid 1:1 hfsc ul rate 100mbit
# child class WITH a link-sharing curve under the curve-less parent
tc class add dev lo parent 1:1 classid 1:2 hfsc ls rate 50mbit
Child'ı activate/deactivate etmek (içinden trafik geçirmek ya da onu silmek)
init_vf()/update_vf()'i sürer; eksik vttree_remove(), free edilmiş child'ı
1:1'in vt-tree'sinden reachable bırakır. Sonraki bir scheduler geçişi ya da
teardown, dangling node'u dereference eder ve bir heap spray'in bir function
pointer kontrolüne ve nihayetinde root'a çevirebileceği bir UAF üretir.
Minimal bir trigger, HFSC vt-tree dolaşması içinde (hfsc_dequeue / vttree ile
ilgili kod) bir KASAN use-after-free splat'i verir.
Detection¶
- KASAN, HFSC vt-tree fonksiyonlarında (
init_vf/update_vf/vttree_*)use-after-free Read/Writeraporlar. - Bir child'ın
ls/sc(link-sharing) taşıdığı ama parent'ının taşımadığı bir HFSC class hiyerarşisinin oluşturulması — alışılmadık bir yapılandırma — özellikle bir unprivileged user namespace içinden, davranışsal imzadır.
Mitigation¶
- Commit
b3d26c5702c7d6c45456326e56d2ccf3f103e60file düzeltildi; eksik validation/removal'ı ekler, böylece inner class'lar doğru ele alınır. CAP_NET_ADMIN'e giden unprivileged path'i kaldırmak için unprivileged namespace'leri kısıtlayın (kernel.unprivileged_userns_clone=0) ve HFSC kullanılmayan yerdeCONFIG_NET_SCH_HFSC'yi disable edin.