Le code BPF peut permettre une élévation locale des privilèges (CVE-2021-29154)
Une autre vulnérabilité visant le sous-système BPF a été divulguée publiquement ces derniers jours (CVE-2021-29154). Il permet aux utilisateurs d'un système utilisant une configuration par défaut du sous-système BPF d'exécuter un code spécialement conçu comme un filtre BPF et d'exécuter un code exécutable arbitraire dans le contexte du noyau.
Selon les fournisseurs, ce problème affecte toutes les distributions utilisant des noyaux jusqu'à la version 5.11.12. Les distributeurs commencent à fournir des correctifs via leurs mécanismes de mise à jour, et KernelCare finalise également des correctifs pour son processus de correction sans redémarrage afin de résoudre ce problème.
En raison de la nature de la fonctionnalité BPF, qui consiste à permettre au code utilisateur d'interagir avec le traitement des paquets réseau au sein du noyau, le potentiel d'attaque est très élevé en cas de faiblesse dans l'implémentation. Cette fonctionnalité spécifique a été abordée récemment dans le bogue du code d'atténuation de Spectre dont il est question ici.
Pour être vulnérable, un système doit être configuré pour autoriser la compilation BPF JIT (par exemple, en définissant "net.core.bpf_jit_enable = 1"). C'est souvent le cas dans les situations où des utilisateurs réguliers effectuent des travaux liés à la manipulation des sockets ou dans les environnements seccomp (secure computing mode) où les permissions sont accordées de manière plus granulaire que la normale.
Le code vulnérable se trouve dans arch/x86/net/bpf_jit_comp.c et arch/x86/net/bpf_jit_comp32.c dans l'arbre du code source du noyau. La faille provient de la façon dont le déplacement de branche se produit lorsque le code utilisateur est compilé, en faisant de mauvaises suppositions concernant l'adresse du code pendant l'optimisation.
Une exploitation correcte de cette vulnérabilité pourrait même conduire à l'évasion des conteneurs ou des chroots, puisque le noyau est partagé entre eux, et que l'exécution de code dans le contexte du noyau lui permet d'échapper aux limites de la conteneurisation.
Comme procédure provisoire, vous pouvez rapidement désactiver BPF JIT en exécutant :
# echo 0 > /proc/sys/net/core/bpf_jit_enable |
qui persistera jusqu'à ce qu'il soit annulé ou qu'un redémarrage du système ait lieu. Une suppression plus permanente peut être obtenue en utilisant l'utilitaire équivalent syscfg de votre distribution pour définir "net.core.bpf_jit_enable=0" au démarrage. Bien sûr, ce type de solution résout le problème en désactivant la fonctionnalité, ce qui est en soi un échec. Si votre système a été configuré pour utiliser BPF JIT, il est fort probable que votre cas d'utilisation nécessitait l'activation explicite de ce paramètre, et vous devriez plutôt vous fier aux correctifs appropriés du noyau, soit par le biais des correctifs de votre distributeur, soit par le biais du processus sans redémarrage de KernelCare.