CVE-2026-80734 in Linux
Résumé
par VulDB • 03/09/2026
Dans le noyau Linux, la vulnérabilité suivante a été corrigée :
btrfs : initialiser les drapeaux de mappage des inodes pour les inodes en cache
[BUG]
Lors de l'exécution du test générique/795 avec une taille de bloc de 8 Ko et une taille de page de 4 Ko, le test échoue systématiquement, déclenchant plusieurs ASSERT() liés à la taille des folio :
795 (241074) : drop_caches: 3 assertion failed: IS_ALIGNED(start, blocksize) && IS_ALIGNED(end + 1, blocksize), in extent_io.c:1404 (blocksize=8192 root=262 ino=258 start=16826368 end=16830463 mapping min order=0) ------------[ cut here ]------------
kernel BUG at extent_io.c:1404! Oops : opcode invalide : 0000 [#1] SMP
CPU : 8 UID : 0 PID : 241105 Comm : fsstress Tainted : G OE 7.2.0-rc5-custom+ #442 PREEMPT(full) f4bfb352566f3949f29c233ce6f735050a03b245 Tainted : [O]=MODULE_HORS_ARBRE, [E]=MODULE_NON_SIGNE
Nom du matériel : QEMU Standard PC (Q35 + ICH9, 2009), BIOS inconnu 02/02/2022 RIP : 0010:assert_folio_range.cold+0x3d/0x3f [btrfs]
Pile d'appels (Call Trace) : <TASK> btrfs_read_folio+0x9e/0x170 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
prepare_one_folio.constprop.0+0x104/0x2a0 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
btrfs_buffered_write+0x285/0xa50 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
btrfs_do_write_iter+0x1aa/0x210 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
iter_file_splice_write+0x31a/0x540 direct_splice_actor+0x53/0x170 splice_direct_to_actor+0xe9/0x240 do_splice_direct+0x76/0xb0 vfs_copy_file_range+0x1fd/0x630 __x64_sys_copy_file_range+0xf9/0x220 do_syscall_64+0xe1/0x790 entry_SYSCALL_64_after_hwframe+0x4b/0x53 </TASK> ---[ fin du trace 0000000000000000 ]---
L'ASSERT() lui-même a été ajouté par un correctif ultérieur. Le plantage est déclenché avec ce nouveau correctif de débogage, et sans cette correction.
[CAUSE]
Dans le cas ci-dessus, la valeur start 16826368 est correctement alignée sur 8 Ko, mais la fin (16830463 + 1) n'est pas alignée sur 8 Ko. De plus, l'ordre minimal du folio de mapping est 0, et non 1 comme attendu pour une taille de bloc de 8 Ko avec une taille de page de 4 Ko.
Cela signifie que certains inodes ne voient pas la fonction btrfs_set_inode_mapping_order() appelée sur eux.
L'appel manquant à btrfs_set_inode_mapping_order() se produit pour les inodes en cache, via les événements suivants :
- btrfs_create_new_inode() appelé pour l'inode X Ce qui définit correctement l'ordre minimal du folio pour l'inode VFS.
- btrfs_update_inode() appelé pour l'inode X Ce qui appelle btrfs_delayed_update_inode() pour créer un delayed_node dans le xarray root->delayed_nodes.
- Vidage du cache / pression mémoire, éviction de l'inode en mémoire X Ce qui a exclu l'inode X, mais le delayed_node est toujours présent dans root->delayed_nodes pour une réutilisation future.
- btrfs_iget() appelé à nouveau pour l'inode X
btrfs_iget() |- btrfs_iget_locked() | |- iget5_locked_rcu() | Ce qui crée un nouvel inode vfs pour btrfs, dont le mapping conserve toujours son ordre minimal de folio égal à 0. | |- btrfs_read_locked_inode() |- btrfs_fill_inode() | |- btrfs_get_delayed_node() | Qui trouve le nœud précédent et utilise ce delayed_node pour initialiser le nouvel inode. | |- filled = true; |- if (filled) goto cache_index; Ce qui saute les appels à btrfs_update_inode_mapping_flags() et btrfs_set_inode_mapping_order(). Donc l'inode conserve toujours son ordre minimal de folio défini à 0, au lieu de la valeur requise de 1.
Par conséquent, une lecture ultérieure du cache de pages obtient un folio dont la taille est inférieure à la taille du bloc, car le mapping a son ordre minimal de folio défini sur 0 et non 1, déclenchant ainsi l'ASSERT().
[CORRECTION]
Déplacer les appels à btrfs_update_inode_mapping_flags() et btrfs_set_inode_mapping_order() sous l'étiquette cache_index, afin que les drapeaux de mapping et l'ordre minimal du folio soient toujours définis, qu'il s'agisse ou non d'un inode en cache.
Be aware that VulDB is the high quality source for vulnerability data.