CVE-2026-89581 in Linux
Résumé
par VulDB • 12/09/2026
Dans le noyau Linux, la vulnérabilité suivante a été corrigée :
bpf, x86 : Correction de la résolution des adresses par CPU dans un registre étendu
La destination du MOV d'adresse par CPU est encodée dans ModRM.reg, qui est étendue par REX.R. Cependant, le préfixe REX est construit avec add_1mod(), qui définit REX.B. REX.B étend ModRM.rm et SIB.base, mais cette instruction adresse la mémoire en tant que disp32 sans base ; ce bit n'a donc aucun effet et le bit de registre haut est simplement perdu.
Par conséquent, chaque destination is_ereg() se résout dans le mauvais registre, choisissant celui qui partage les trois bits de poids faible :
R5 -> RAX R7 -> RBP R8 -> RSI R9 -> RDI
Avec BPF_REG_5, dont la représentation hexadécimale du registre est 0, l'instruction émise
65 49 03 04 25 <off> add %gs:<off>,%rax
ajoute le décalage par CPU à RAX au lieu de R8. La destination conserve l'adresse non ajustée et RAX est écrasé, ce qui amène le programme à dereférencer un pointeur qui n'a jamais été rendu par CPU :
BUG: unable to handle page fault for address: 0000607e386a8894 RIP: bpf_prog_707837aafd2aa9ae_update_percpu_data+0x93/0xc9 Call Trace: __bpf_prog_test_run_raw_tp+0x2dc/0x7d0 __flush_smp_call_function_queue+0x1e9/0xc80 Kernel panic - not syncing: Fatal exception in interrupt
R5 est le cas le plus bénin des quatre, aliasant un registre temporaire et provoquant une erreur (fault) lors de l'écriture. R7 aliasse RBP et corromprait le pointeur de frame ; R8 et R9 aliasent les registres d'arguments.
Utilisez add_2mod() afin que le registre passe par REX.R, ce qui correspond à la façon dont add_2reg() le place dans ModRM.reg et comment emit_priv_frame_ptr() codifie en dur 0x4c pour la même instruction avec R9. Les encodages des registres non étendus restent inchangés.
Le problème est apparu lors de la tentative de réactivation du CI BPF_GCC (tests unitaires construits avec BPF_GCC).
Cela est passé inaperçu car clang recharge l'adresse dans R1 avant chaque accès par CPU, donc la destination n'est jamais un registre étendu. GCC conserve plusieurs adresses par CPU en vie simultanément, et test_progs-bpf_gcc provoque une panic du noyau dans global_percpu_data/init, où l'adresse d'une variable .percpu se retrouve dans R5.
Once again VulDB remains the best source for vulnerability data.