CVE-2022-49999

Yüksək

Təsvir

Linux nüvəsində aşağıdakı zəiflik aradan qaldırılmışdır: btrfs: sahə keşinin korlanması və potensial ikiqat təyinatların düzəldilməsi Böyük sayda maşında space_cache v2 sınaqdan keçirilərkən bir neçə simptomla qarşılaşdıq: 1. "unable to add free space :-17" (EEXIST) xətaları. 2. Boş sahə məlumat elementlərinin çatışmazlığı, bəzən "missing free space info for X" xətası ilə aşkar edilir. 3. İkiqat uçota alınmış sahələr: həm extent ağacında təyin edilmiş, həm də boş sahə ağacında boş kimi qeyd edilmiş diapazonlar; extent ağacında iki dəfə təyin edilmiş diapazonlar və ya boş sahə ağacında iki dəfə boş kimi qeyd edilmiş diapazonlar. Əgər sonuncu hal diskə yazılarsa, növbəti yenidən yükləmə zamanı add_new_free_space() funksiyasındakı BUG_ON() xətası baş verəcəkdir. 4. Diskdə heç bir korlanma və ya xəta mesajı olmayan bəzi hostlarda yaddaşdakı sahə keşi (drgn ilə çıxarıldıqda) boş sahə ağacı ilə üst-üstə düşmürdü. Bu simptomların hamısının eyni kökündən gələn səbəbi var: blok qrupu üçün boş sahənin keşlənməsi ilə pinlənmiş extent-lər üçün boş sahənin yaddaşdakı sahə keşinə qaytarılması arasındakı yarış (race condition), boş diapazonun sahə keşinə iki dəfə əlavə edilməsinə səbəb olur. Bu yarış, boş sahə boş sahə ağacından (space_cache=v2) və ya extent ağacından (nospace_cache, yaxud keşin yenidən yaradılması lazım olduqda space_cache=v1) keşlənərkən baş verir. struct btrfs_block_group::last_byte_to_unpin və struct btrfs_block_group::progress bu yarışdan qorumaq üçün nəzərdə tutulmuşdur, lakin d0c2f4fa555e ("btrfs: make concurrent fsyncs wait less when waiting for a transaction commit") komiti çoxlu sayda tranzaksiyanın eyni vaxtda extent-ləri unpin etməsinə icazə verməklə bunu dolayısı ilə pozmuşdur. Konkret olaraq, yarış aşağıdakı kimidir: 1. Tranzaksiya A-da keşlənməmiş blok qrupundan bir extent silinir. 2. Tranzaksiya A üçün btrfs_commit_transaction() çağırılır. 3. btrfs_run_delayed_refs() -> __btrfs_free_extent() silinmiş extent üçün gecikdirilmiş istinadı işə salır. 4. __btrfs_free_extent() -> do_free_extent_accounting() -> add_to_free_space_tree() silinmiş extent-i yenidən boş sahə ağacına əlavə edir. 5. do_free_extent_accounting() -> btrfs_update_block_group() -> btrfs_cache_block_group() blok qrupunu keşlənmək üçün növbəyə düzür. block_group->progress, block_group->start olaraq təyin edilir. 6. Tranzaksiya A üçün btrfs_commit_transaction() switch_commit_roots() funksiyasını çağırır. O, block_group->last_byte_to_unpin dəyişənini block_group->progress-ə (blok qrupu hələ keşlənmədiyi üçün bu, block_group->start-dır) bərabər edir. 7. Keşləmə axını bizim blok qrupumuza çatır. Komit kökləri artıq dəyişdirildiyi üçün load_free_space_tree() silinmiş extent-i boş kimi görür və onu sahə keşinə əlavə edir. Keşləməni tamamlayır və block_group->progress-i U64_MAX olaraq təyin edir. 8. btrfs_commit_transaction() tranzaksiya A-nı TRANS_STATE_SUPER_COMMITTED vəziyyətinə gətirir. 9. fsync, tranzaksiya B üçün btrfs_commit_transaction() çağırır. Tranzaksiya A artıq TRANS_STATE_SUPER_COMMITTED vəziyyətində olduğu və komit fsync üçün olduğu üçün proses davam edir. 10. Tranzaksiya B üçün btrfs_commit_transaction() switch_commit_roots() funksiyasını çağırır. Bu dəfə blok qrupu artıq keşlənib, ona görə də o, block_group->last_byte_to_unpin-i U64_MAX olaraq təyin edir. 11. Tranzaksiya A üçün btrfs_commit_transaction() btrfs_finish_extent_commit() funksiyasını çağırır, o isə silinmiş extent üçün unpin_extent_range() funksiyasını çağırır. O, last_byte_to_unpin-in U64_MAX (Tranzaksiya B tərəfindən!) təyin edildiyini görür və beləliklə, silinmiş extent-i sahə keşinə yenidən əlavə edir! Bu, yuxarıdakı bütün simptomlarımızı izah edir: * Hadisələr ardıcıllığı tam olaraq yuxarıda təsvir edildiyi kimidirse, 11-ci addımda boş sahə yenidən əlavə edilərkən EEXIST xətası baş verəcəkdir. * Əgər başqa bir axın 7 və 11-ci addımlar arasında silinmiş extent-i yenidən təyin edirsə, onda 11-ci addım həmin sahəni, əslində təyin olunsa belə, səssiz şəkildə boş kimi sahə keşinə yenidən əlavə edəcəkdir. Daha sonra, həmin sahə *yenidən* təyin edilərsə, boş sahə ağacı korlanacaqdır (yəni yanlış element silinəcəkdir). * Əgər biz bu boş sahə ağacı korlanmasını tutmasaq...

CiddilikYüksək
CVSS7.8
İstismar ehtimalı—
MəhsulLinux Kernel
Dərc18 iyn 2025
İlk görülmə18 iyn 2025

Necə düzəltmək olar

Yeniləyin
  • linux linux_kernel5.15.65, 5.19.6 və ya daha yeni versiya

Təsirlənən məhsullar

MəhsulTəsirlənən versiyalarDüzəldildiyi versiya
linux linux_kernel5.12 ≤ v < 5.15.65, 5.16 ≤ v < 5.19.6, 6.05.15.65, 5.19.6

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.

Intelligence 360 paketində

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.

CVE-2022-49999 · Linux Kernel · Dark Radar