CVE-2022-49547
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılıb: btrfs: boş məlumat sahəsi az olduqda eyni vaxtda baş verən dio yazmaları arasındakı deadlock probleminin həlli Birbaşa IO (direct IO) yazması üçün məlumat sahəsi rezerv edərkən, əgər bir neçə tapşırıq faylın eyni diapazonuna yazmağa çalışırsa, həmin fayl diapazonu tərəfindən əhatə olunan çoxlu sayda extent varsa, mövcud məlumat sahəsi azdırsa və yazmalar inode-un i_size dəyərini genişləndirmirsə, deadlock yaranmış ola bilər. Deadlock bu şəkildə baş verə bilər: 1) i_size dəyəri 1M olan bir faylımız var; 0 ofsetində ölçüsü 128K olan bir extent və 128K ofsetində yenə ölçüsü 128K olan digər bir extent var; 2) Tapşırıq A [0, 256K) fayl diapazonuna birbaşa IO yazması həyata keçirir və yazma i_size sərhədləri daxilində olduğu üçün inode kilidini (VFS səviyyəsində) paylaşım rejimində götürür; 3) Tapşırıq A btrfs_dio_iomap_begin() funksiyasında [0, 256K) fayl diapazonunu kilidləyir və sonra [0, 128K) diapazonunu əhatə edən extent üçün extent xəritəsini əldə edir. btrfs_get_blocks_direct_write() funksiyasında həmin fayl diapazonu ([0, 128K)) üçün sıralanmış (ordered) extent yaradır; 4) btrfs_dio_iomap_begin() funksiyasından geri dönməzdən əvvəl [0, 256K) fayl diapazonunun kilidini açır; 5) Tapşırıq A btrfs_dio_iomap_begin() funksiyasını bu dəfə [128K, 256K) fayl diapazonu üçün yenidən icra edir və [128K, 256K) fayl diapazonunu kilidləyir; 6) Tapşırıq B də [0, 256K) fayl diapazonuna birbaşa IO yazmasına başlayır. O da i_size limiti daxilində olduğu üçün inode-u paylaşım rejimində kilidləyir və sonra [0, 256K) fayl diapazonunu kilidləməyə çalışır. O, [0, 128K) alt-diapazonunu kilidləyə bilir, lakin hazırda tapşırıq A tərəfindən kilidlənmiş [128K, 256K) diapazonunu gözləyərək bloklanır; 7) Tapşırıq A btrfs_get_blocks_direct_write() funksiyasına daxil olur və məlumat sahəsi rezerv etməyə çalışır. Mövcud boş sahə az olduğu üçün bu, asinxron məlumatların geri qaytarılması (async data reclaim) tapşırığını tetikləyir və onun məlumat sahəsi rezerv etməsini gözləyir; 8) Asinxron geri qaytarma tapşırığı bütün mövcud sıralanmış extentlərin tamamlanmasını (btrfs_wait_ordered_roots() vasitəsilə) gözləməyə qərar verir. O, daha əvvəl tapşırıq A tərəfindən [0, 128K) fayl diapazonu üçün yaradılmış sıralanmış extenti tapır və onun tamamlanmasını gözləyir; 9) [0, 128K) fayl diapazonu üçün sıralanmış extent tamamlana bilmir, çünki [0, 128K) fayl diapazonunu kilidləməyə çalışarkən btrfs_finish_ordered_io() funksiyasında bloklanır. Bu, deadlock ilə nəticələnir, çünki: - tapşırıq B [0, 128K) fayl diapazonunu kilidli saxlayır və [128K, 256K) diapazonunun tapşırıq A tərəfindən kilidinin açılmasını gözləyir; - tapşırıq A [128K, 256K) fayl diapazonunu kilidli saxlayır və asinxron məlumatların geri qaytarılması tapşırığının onun sahə rezervasiyası sorğusunu yerinə yetirməsini gözləyir; - asinxron məlumatların geri qaytarılması tapşırığı [0, 128K) sıralanmış extentinin tamamlanmasını gözləyir, lakin sıralanmış extent tamamlana bilmir, çünki [0, 128K) fayl diapazonu hazırda tapşırıq B tərəfindən kilidlənib; tapşırıq B isə tapşırıq A-nın [128K, 256K) fayl diapazonunun kilidini açmasını, tapşırıq A isə asinxron məlumatların geri qaytarılması tapşırığını gözləyir. Bu, 4 tapşırıq arasında deadlockla nəticələnir: tapşırıq A, tapşırıq B, asinxron məlumatların geri qaytarılması tapşırığı və sıralanmış extentin tamamlanmasını həyata keçirən tapşırıq (iş növbəsi tapşırığı - work queue task). Bu növ deadlock fstests-dən generic/300 test halı tərəfindən sporadik olaraq tetiklene bilər və aşağıdakı kimi stack trace ilə nəticələnir: [12084.033689] INFO: task kworker/u16:7:123749 blocked for more than 241 seconds. [12084.034877] Not tainted 5.18.0-rc2-btrfs-next-115 #1 [12084.035562] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [12084.036548] task:kworker/u16:7 state:D stack: 0 pid:123749 ppid: 2 flags:0x00004000 [12084.036554] Workqueue: btrfs-flush_delalloc btrfs_work_helper [btrfs] [12084.036599] Call Trace: [12084.036601] <TASK> [12084.036606] __schedule+0x3cb/0xed0 [12084.036616] schedule+0x4e/0xb0 [12084.036620] btrfs_start_ordered_extent+0x109/0x1c0 [btrfs] [12084.036651] ? prepare_to_wait_exclusive+0xc0/0xc0 [12084.036659] btrfs_run_ordered_extent_work+0x1a/0x30 [btrfs] [12084.036688] btrfs_work_helper+0xf8/0x400 [btrfs] [12084.0367 ---truncated---
Necə düzəltmək olar
- linux linux_kernel5.16, 5.18.3 və ya daha yeni versiya
Təsirlənən məhsullar
| Məhsul | Təsirlənən versiyalar | Düzəldildiyi versiya |
|---|---|---|
| linux linux_kernel | 5.15.27 ≤ v < 5.16, 5.16.13 ≤ v < 5.18.3 | 5.16, 5.18.3 |
Versiyanızı yoxlayın
Məhsulu seçin və istifadə etdiyiniz versiyanı yazın; versiyanın təsirlənən aralıqda olub-olmadığını görün.
Attack Surface Management
Domenlərinizə bağlı aktivləri, onlarda işləyən texnologiyaları və məlum zəiflikləri bir siyahıda görün.