CVE-2025-38472
Açıklama
Linux çekirdeğinde aşağıdaki güvenlik açığı giderilmiştir: netfilter: nf_conntrack: başlatılmamış girdinin kaldırılması nedeniyle oluşan çökme düzeltildi conntrack girdisi hash bucket listesinden çıkarılmaya çalışılırken bir çökme bildirildi: [exception RIP: __nf_ct_delete_from_lists+172] [..] #7 [ff539b5a2b043aa0] nf_ct_delete at ffffffffc124d421 [nf_conntrack] #8 [ff539b5a2b043ad0] nf_ct_gc_expired at ffffffffc124d999 [nf_conntrack] #9 [ff539b5a2b043ae0] __nf_conntrack_find_get at ffffffffc124efbc [nf_conntrack] [..] nf_conn yapısı slab'den ayrılmış olarak işaretlenmiş ancak kısmen başlatılmış durumda görünüyor: ct hlist işaretçisi çöp değer içeriyor; ct hash değerine benziyor (dolayısıyla çökme). ct->status değeri IPS_CONFIRMED|IPS_DYING değerine eşit, bu beklenen bir durum ct->timeout değeri 30000 (=30s), bu beklenmeyen bir durum. Geri kalan her şey normal bir udp conntrack girdisi gibi görünüyor. ct->status değerini yok sayıp 0 kabul edersek, girdi yeni ayrılmış ancak henüz hash'e eklenmemiş girdilerle eşleşiyor: - ct hlist işaretçileri aşırı yüklenmiş ve ham tuple hash değerini saklıyor/önbelleğe alıyor - ct->timeout değeri, mutlak 'jiffies' değeri yerine yeni bir udp akışı için beklenen göreli süreyle eşleşiyor. IPS_CONFIRMED biti olmasaydı, __nf_conntrack_find_get() girdiyi atlayacaktı. Teori, aşağıdaki yarış durumuna çarptığımız yönünde: cpu x cpu y cpu z E girdisini buldu E girdisini buldu E süresi dolmuş <önalım> nf_ct_delete() E'yi rcu slab'e geri döndürdü init_conntrack E yeniden başlatıldı, ct->status 0 olarak ayarlandı reply tuplehash hnnode.pprev hash değerini saklıyor. cpu y, E'yi cpu x'te silinmesinden hemen önce buldu. E şimdi cpu z'de yeniden başlatıldı. cpu y, süre dolumu ve/veya confirm bitini kontrol etmeden önce önalıma uğradı. ->refcnt 1 olarak ayarlandı E artık skb'ye ait ->timeout 30000 olarak ayarlandı cpu y şimdi devam etseydi, E'yi süresi dolmuş olarak gözlemleyecek ancak eksik CONFIRMED biti nedeniyle E'yi atlayacaktı. nf_conntrack_confirm çağrıldı ayarlar: ct->status |= CONFIRMED Bu yanlış: E henüz hashtable'a eklenmedi. cpu y devam ediyor, E'yi süresi dolmuş ancak CONFIRMED olarak gözlemliyor: <devam ediyor> nf_ct_expired() -> evet (ct->timeout 30s) confirmed biti ayarlı. cpu y, E'yi hashtable'dan silmeye çalışacak: nf_ct_delete() -> DYING bitini ayarla __nf_ct_delete_from_lists Bu senaryo bile bir çökmeyi garanti etmez: cpu z hâlâ tablo bucket kilidini/kilitlerini tutuyor, bu nedenle y bloke olur: z tarafından tutulan spinlock'u bekle CONFIRMED ayarlı ancak ct'nin hash'e ekleneceğine dair bir garanti yok: "chaintoolong" veya "clash resolution" mantığının ikisi de ekleme adımını atlar. reply hnnode.pprev hâlâ hash değerini saklıyor. spinlock'u serbest bırakır NF_DROP döndürür <bloke kalkar, ardından hlist_nulls_del_rcu pprev üzerinde çöker> CPU z girdiyi hashtable'a eklerse, cpu y E'yi hemen tekrar çıkaracak ancak çökme oluşmayacaktır. 'cpu y' yarış durumu olmadan, 'çöp' hlist sonuç doğurmaz: ct refcnt 1'de kalır, sonunda skb serbest bırakılır ve E şu yolla yok edilir: nf_conntrack_put -> nf_conntrack_destroy -> nf_ct_destroy. Bunu çözmek için IPS_CONFIRMED atamasını tablo eklemesinden sonra ancak kilit açılmadan önce taşıyın. Pablo, confirm-bit-store işleminin hlist eklemesine veya timeout düzeltmesine göre yeniden sıralanabileceğine dikkat çekiyor, bu nedenle bunu önlemek için set_bit ve before_atomic bellek bariyerine geçin. Diğer CPU'ların CONFIRMED biti ayarlanmadan hemen önce yeni eklenmiş bir girdiyi gözlemleyip gözlemleyememesi önemli değildir: Böyle bir olay yukarıdaki "E eski enkarnasyondur" durumundan ayırt edilemez: girdi atlanacaktır. Ayrıca nf_ct_should_gc() işlevini önce confirmed bitini kontrol edecek şekilde değiştirin. gc sırası şöyledir: 1. Girdinin süresinin dolup dolmadığını kontrol et, dolmadıysa sonraki girdiye geç 2. Süresi dolmuş girdiye bir referans al. 3. 1. adımı iki kez kontrol etmek için nf_ct_should_gc() işlevini çağır. Bu nedenle nf_ct_should_gc() yalnızca süre dolumu kontrolünde zaten başarısız olmuş girdiler için çağrılır. Bu yamadan sonra, confirmed biti kontrolü geçtiğinde ---kesildi---
Nasıl düzeltilir
- linux linux_kernel6.1.147, 6.6.100, 6.12.40, 6.15.8 ya da sonraki bir sürüm
Etkilenen ürünler
| Ürün | Etkilenen sürümler | Düzeltildiği sürüm |
|---|---|---|
| linux linux_kernel | 5.18.13 ≤ v < 6.1.147, 6.2 ≤ v < 6.6.100, 6.7 ≤ v < 6.12.40, 6.13 ≤ v < 6.15.8, 6.16 | 6.1.147, 6.6.100, 6.12.40, 6.15.8 |
| debian debian_linux | 11.0 | — |
Sürümünüzü kontrol edin
Ürünü seçin ve kullandığınız sürümü yazın; sürümün etkilenen aralıkta olup olmadığını görün.
Attack Surface Management
Alan adlarınıza bağlı varlıkları, bu varlıklarda çalışan teknolojileri ve bilinen zafiyetleri tek listede görün.