CVE-2026-31519
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılmışdır: btrfs: subvol yaradılması zamanı BTRFS_ROOT_ORPHAN_CLEANUP təyin edilsin Son vaxtlar xarab olmuş dentry-ləri olan bir sıra subvolume-lar müşahidə edilmişdir. Valideyn kataloquna ls-ing etdikdə nəticə belə görünür: drwxrwxrwt 1 root root 16 Jan 23 16:49 . drwxr-xr-x 1 root root 24 Jan 23 16:48 .. d????????? ? ? ? ? ? broken_subvol Və eyni şəkildə faylın stat-ing prosesi uğursuz olur. Bu vəziyyətdə subvol-un silinməsi ENOENT ilə uğursuz olur, lakin onun üzərində yeni fayl və ya subvol yaratmağa cəhd etdikdə EEXIST xətası baş verir və hətta fs dayandırılır. Bu bizi çətin vəziyyətdə qoyur. dmesg-də tək bir diqqətçəkən xəta mesajı var: "could not do orphan cleanup -2" 2 rəqəmi ENOENT-dir və xəta btrfs_orphan_cleanup()-in xəta idarəetmə yolundan gəlir, stek isə btrfs_lookup()-a geri gedir. btrfs_lookup btrfs_lookup_dentry btrfs_orphan_cleanup // bu mesajı çap edir və -ENOENT qaytarır Daxili vəziyyətin ətraflı araşdırılmasından sonra aydın oldu ki: - subvol üçün heç bir yetim (orphan) element yoxdur - subvol digər hallarda sağlam görünür, yarıda silinmiş və ya buna bənzər bir vəziyyətdə deyil, silinmə prosesi (drop progress) yoxdur və s. - subvol bir müddət əvvəl yaradılıb və BTRFS_ROOT_ORPHAN_CLEANUP-u təyin edən ilk mənalı btrfs_orphan_cleanup() çağırışı çox daha gec baş verir. - btrfs_orphan_cleanup() uğursuz olduqdan sonra btrfs_lookup_dentry() -ENOENT qaytarır, bu isə d_splice_alias(NULL, dentry) vasitəsilə subvolume üçün mənfi dentry ilə nəticələnir və müşahidə olunan davranışa səbəb olur. Xətanı dentry keşini təmizləyərək azaltmaq olar, bu nöqtədə istəsək subvolume-nu uğurla silə bilərik. Yəni, btrfs_lookup() btrfs_lookup_dentry() if (!sb_rdonly(inode->vfs_inode)->vfs_inode) btrfs_orphan_cleanup(sub_root) test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) btrfs_search_slot() // inode N üçün yetim elementi tapır ... "could not do orphan cleanup -2" çap edir if (inode == ERR_PTR(-ENOENT)) inode = NULL; return d_splice_alias(NULL, dentry) // valid subvolume üçün MƏNFİ DENTRY btrfs_orphan_cleanup() işə düşdükdə kök (root) üzərində test_and_set_bit(BTRFS_ROOT_ORPHAN_CLEANUP) yerinə yetirir, ona görə də verilmiş kökdə birdən çox dəfə işləyə bilməz, deməli paralel olaraq başqa bir şey işləməlidir. Lakin, nlinks 0-a endikdə yetimi silməyin aşkar yolları, əvvəlcə subvolume-da axtarış aparmadan işləyə bilməməlidir, bu axtarış isə btrfs_orphan_cleanup()-i işə salmalı və biti təyin etməlidir. Sonuncu vacib müşahidə ondan ibarətdir ki, create_subvol() funksiyası d_instantiate_new()-i çağırır, lakin BTRFS_ROOT_ORPHAN_CLEANUP-u təyin etmir, buna görə də dentry keşi təmizləndikdə, subvolume-da növbəti axtarış ilk dəfə btrfs_orphan_cleanup()-ə real çağırış edəcəkdir. Bu, inode/yetim elementlərinin paralel şəkildə silinməsi imkanını açır, lakin ən tipik evict() yolları valideyn dentry üzərində istinadı saxlayacaq (child dentry, d_alloc()-da dget vasitəsilə parent->d_lockref.count-u saxlayır, __dentry_kill()-də azad edilir) və valideynin dentry keşindən çıxarılmasının qarşısını alacaqdır. Tək istisna gecikdirilmiş iput-lardır. Sifarişli extent yaradılması inode üzərində igrab() çağırır. Əgər bu istinadlar saxlanıldığı halda fayl unlink edilirsə və bağlanırsa, __dentry_kill()-dəki iput() i_count-u azaldır, lakin eviction-u tetikləmir (i_count > 0). Child dentry azad edilir və subvol dentry-sinin d_lockref.count-u 0-a düşür, bu da inode hələ canlı olduğu halda onu evictable edir. İki yarış (race condition) olduğundan (writeback ilə unlink arasındakı yarış və axtarış ilə gecikdirilmiş iput-lar arasındakı yarış) və çox sayda dəyişən hissə olduğundan, aşağıdakı üç diaqram tam mənzərəni göstərir. (Yalnız ikincisi və üçüncüsü yarışdır) Mərhələ 1: BTRFS_ROOT_ORPHAN_CLEANUP təyin olunmadan dentry keşində Subvol Yaradılması btrfs_mksubvol() lookup_one_len() __lookup_slow() d_alloc_parallel() __d_alloc() // d_lockref.count = 1 create_subvol(dentry) // bitə toxunmur.. d_instantiate_new(dentry, inode) // d_lockref.c ilə keşdə dentry ---kəsilmiş---
Necə düzəltmək olar
- linux linux_kernel2.6.33, 6.1.168, 6.6.131, 6.12.80, 6.18.21, 6.19.11 və ya daha yeni versiya
- git.kernel.org/stable/c/2ec578e6452138ab76f6c9a9c18711fcd197649f
- git.kernel.org/stable/c/5131fa077f9bb386a1b901bf5b247041f0ec8f80
- git.kernel.org/stable/c/696683f214495db3cdacab9a713efaaced8660f8
- git.kernel.org/stable/c/a41a9b8d19a98b45591528c6e54d31cc66271d1e
- git.kernel.org/stable/c/c57276ced3c3207f42182dfa2f0d8e860357e111
- git.kernel.org/stable/c/d43da8de0ed376abafbad8a245a1835e8f66cb0f
Təsirlənən məhsullar
| Məhsul | Təsirlənən versiyalar | Düzəldildiyi versiya |
|---|---|---|
| linux linux_kernel | 2.6.32.19 ≤ v < 2.6.33, 2.6.33 ≤ v < 6.1.168, 6.2 ≤ v < 6.6.131, 6.7 ≤ v < 6.12.80, 6.13 ≤ v < 6.18.21, 6.19 ≤ v < 6.19.11, 7.0 | 2.6.33, 6.1.168, 6.6.131, 6.12.80, 6.18.21, 6.19.11 |
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.