CVE-2021-47069
Açıklama
Linux kernel içerisinde aşağıdaki güvenlik açığı giderilmiştir: ipc/mqueue, msg, sem: süresi dolmuş bir yığın referansına güvenmekten kaçının do_mq_timedreceive, wq_sleep fonksiyonunu yerel bir yığın adresiyle çağırır. Gönderici (do_mq_timedsend), daha sonra pipelined_send fonksiyonunu çağırmak için bu adresi kullanır. Bu durum, tetiklenmesi oldukça zor olan ve do_mq_timedreceive çağrısının geri dönerek do_mq_timedsend'in geçersiz bir adrese güvenmesine yol açan bir yarış durumuna (race condition) neden olur; bu da şu çökmeye sebebiyet verir: RIP: 0010:wake_q_add_safe+0x13/0x60 Call Trace: __x64_sys_mq_timedsend+0x2a9/0x490 do_syscall_64+0x80/0x680 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f5928e40343 Yarış durumu şu şekilde gerçekleşir: 1. do_mq_timedreceive, wq_sleep fonksiyonunu fonksiyon yığını üzerindeki `struct ext_wait_queue` adresiyle (burada `ewq_addr` olarak takma adlandırılmıştır) çağırır - yığın üzerine yazılmadığı sürece geçerli bir `struct ext_wait_queue *` tutar. 2. `ewq_addr`, wq_add içinde info->e_wait_q[RECV].list kısmına eklenir ve do_mq_timedsend, __pipelined_op fonksiyonunu çağırmak için bunu wq_get_first_waiter(info, RECV) aracılığıyla alır. 3. Gönderici, __pipelined_op::smp_store_release(&this->state, STATE_READY) fonksiyonunu çağırır. Yarış penceresi burada başlar. (`this`, `ewq_addr`'dir.) 4. Eğer alıcı şu anda do_mq_timedreceive::wq_sleep içinde uyanırsa, `state == STATE_READY` olduğunu görür ve döngüden çıkar. 5. do_mq_timedreceive geri döner ve `ewq_addr` artık bir `struct ext_wait_queue *` olma garantisine sahip değildir çünkü do_mq_timedreceive'in yığını üzerindeydi. (Adres, başka bir fonksiyon ona dokunana kadar üzerine yazılmayabilir, bu da belirsiz bir süre boyunca orada kalabileceği anlamına gelir.) 6. do_mq_timedsend::__pipelined_op(), hala `ewq_addr`'nin bir `struct ext_wait_queue *` olduğuna inanır ve onu wake_q_add_safe çağrısına iletilecek bir task_struct bulmak için kullanır. Şanslı durumda, henüz hiçbir şey `ewq_addr` üzerine yazmamışsa, `ewq_addr->task` doğru task_struct'tır. Şanssız durumda ise __pipelined_op::wake_q_add_safe, alıcının task_struct'ı olarak sahte bir adres alır ve bu da çökmeye neden olur. do_mq_timedsend::__pipelined_op(), STATE_READY değerini ayarladıktan sonra `this` referansını çözmemelidir, çünkü alıcı taraf artık geri dönmekte özgürdür. __pipelined_op, alıcının yığınında bulunan `this` referansını çözmek yerine, get_task_struct tarafından döndürülen alıcının task_struct'ı üzerinde wake_q_add_safe fonksiyonunu çağıracak şekilde değiştirilmiştir. Manfred'in belirttiği üzere, aynı yarış durumu potansiyel olarak ipc/msg.c::expunge_all ve ipc/sem.c::wake_up_sem_queue_prepare bölümlerinde de mevcuttur. Bunlar da aynı yöntemle düzeltilmiştir.
Nasıl düzeltilir
- linux linux_kernel5.10.40, 5.12.7 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.6 ≤ v < 5.10.40, 5.11 ≤ v < 5.12.7, 5.13 | 5.10.40, 5.12.7 |
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.