CVE-2024-56687
Açıklama
Linux kernel içerisinde aşağıdaki güvenlik açığı giderilmiştir: usb: musb: İlk Rx uç nokta isteğindeki donanım kilitlenmesi düzeltildi Bir isteğin geri çağırma fonksiyonunun (callback) usb_ep_queue() üzerinden çağrılma olasılığı vardır (eksik çağrıların eklendiği çağrı izi aşağıdadır): req->complete from usb_gadget_giveback_request (drivers/usb/gadget/udc/core.c:999) usb_gadget_giveback_request from musb_g_giveback (drivers/usb/musb/musb_gadget.c:147) musb_g_giveback from rxstate (drivers/usb/musb/musb_gadget.c:784) rxstate from musb_ep_restart (drivers/usb/musb/musb_gadget.c:1169) musb_ep_restart from musb_ep_restart_resume_work (drivers/usb/musb/musb_gadget.c:1176) musb_ep_restart_resume_work from musb_queue_resume_work (drivers/usb/musb/musb_core.c:2279) musb_queue_resume_work from musb_gadget_queue (drivers/usb/musb/musb_gadget.c:1241) musb_gadget_queue from usb_ep_queue (drivers/usb/gadget/udc/core.c:300) usb_ep_queue() fonksiyonunun dokümantasyonuna göre bu durum gerçekleşmemelidir: "Not edin ki @req'in ->complete() geri çağırması asla usb_ep_queue() içerisinden çağrılmamalıdır çünkü bu durum ölü kilitleme (deadlock) durumları yaratabilir." Aslında, aşağıdaki dizide bir donanım kilitlenmesi meydana gelebilir: 1. Gadget, musb_gadget_enable() kullanılarak başlatılır. 2. Bu sırada bir paket gelir ve RXPKTRDY bayrağı ayarlanarak bir kesme (interrupt) tetikler. 3. Eğer IRQ'lar etkinse, kesme işlenir ancak musb_g_rx() boş bir kuyruk bulur (next_request() NULL döner). Kesme bayrağı yapıştırıcı katman yöneticisi tarafından zaten temizlenmiştir ancak RXPKTRDY bayrağı ayarlı kalmaya devam eder. 4. İlk istek usb_ep_queue() kullanılarak kuyruğa eklenir ve yukarıdaki çağrı izinde gösterildiği gibi req->complete() çağrısına yol açar. 5. Geri çağırma işlemi IRQ'ları etkinleştirirse ve başka bir paket bekliyorsa, adım (3) tekrarlanır. İstek kuyruğu boştur çünkü usb_g_giveback() geri çağırmayı yürütmeden önce isteği kaldırır. 6. Donanımın RXPKTRDY bayrağını ayarlamasıyla tetiklenen kesme işlendiği halde bayrağın kendisi ayarlı kaldığından, uç nokta kilitli kalır. Bu senaryonun gerçekleşmesi için, complete geri çağırması sırasında herhangi bir noktada IRQ'ların etkinleştirilmiş olması yeterlidir. Bu durum, rx_complete() geri çağırmasının netif_rx() fonksiyonunu çağırdığı USB Ethernet gadget ile meydana gelir. Görev bağlamında (task context) çağrıldığında, netif_rx() alt yarımları (bottom halves - BHs) devre dışı bırakır. BH'ler yeniden etkinleştirildiğinde, yumuşak kesmelerin (soft IRQs) işlenmesine izin vermek için IRQ'lar da etkinleştirilir. Gadget'ın kendisi modül yüklemesinde (veya yerleşik olarak derlendiyse önyükleme sırasında) başlatılır, ancak ilk istek ağ arayüzü ayağa kaldırıldığında kuyruğa eklenir ve ioctl() aracılığıyla görev bağlamında rx_complete()'i tetikler. Arayüz kapalıyken bir paket gelirse, bu durum arayüzün USB ana bilgisayarından daha fazla paket almasını engelleyebilir. Durum oldukça karmaşıktır ve birçok taraf söz konusudur. Bu özel sorun birkaç olası yolla çözülebilir: 1. Geri çağırmaların asla IRQ'ları etkinleştirmediğinden emin olmak. netif_rx()'in kesmelerle nasıl etkileşime girdiğini keşfetmek bile oldukça zor olduğundan ve u_ether tek fonksiyon sürücüsü olmadığından bunu uygulamak zor olacaktır. Benzer "hatalar" diğer sürücülerde de gizli olabilir. 2. Geri çağırmayı çağırmadan önce musb_g_giveback() içinde MUSB kesmelerini devre dışı bırakmak ve sonrasında tekrar etkinleştirmek (örneğin musb_{dis,en}able_interrupts() çağrılarak). Bu, IRQ'lar etkin olsa bile geri çağırma sırasında MUSB kesmelerinin işlenmeyeceğini garanti eder. Aslında, kilit serbest bırakılırken IRQ'ların etkinleştirilmesine izin verir. Ancak bu, zarif olmayan bir geçici çözüm (hack) gibi görünmektedir. 3. İstek kuyruğu boşsa RXPKTRDY bayrağını temizlemek için kesme yöneticisini değiştirmek. Bu yaklaşım da bir geçici çözüm gibi görünse de, yazılım onları işlemeye hazır değilken gelen paketleri işlemeye çalışarak CPU zamanını boşa harcar. 4. musb_ep_restart() içinde rxstate() çağırmak yerine Rx FIFO'yu boşaltmak. Bu, kuyrukta en az bir istek olduğunda donanımın paket alabileceğinden emin olur. Bir kez...
Nasıl düzeltilir
- linux linux_kernel6.1.120, 6.6.64, 6.11.11, 6.12.2 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 ≤ v < 6.1.120, 6.2 ≤ v < 6.6.64, 6.7 ≤ v < 6.11.11, 6.12 ≤ v < 6.12.2 | 6.1.120, 6.6.64, 6.11.11, 6.12.2 |
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.