STACKLEAK est une fonctionnalité de sécurité du noyau Linux développée à l'origine par les créateurs de Grsecurity / PaX. J'ai décidé d'apporter STACKLEAK au noyau vanilla officiel (Linux kernel mainline). Cet article parlera de la structure interne, des propriétés de cette fonction de sécurité et de son très long chemin difficile dans la ligne principale.

STACKLEAK protège contre plusieurs classes de vulnérabilités dans le noyau Linux, à savoir:
- réduit les informations utiles à l'attaquant, qui peuvent être divulguées de la pile nucléaire vers l'espace utilisateur;
- bloque certaines attaques sur des variables non initialisées dans la pile du noyau;
- fournit des outils de détection de débordement de pile dynamique.
Cette fonctionnalité de sécurité correspond parfaitement au concept du projet d'autoprotection du noyau (KSPP): la sécurité est plus que la simple correction de bogues. Absolument toutes les erreurs dans le code ne peuvent pas être corrigées, et donc le noyau Linux devrait fonctionner en toute sécurité dans des situations d'erreur, y compris lors de la tentative d'exploitation de vulnérabilités. Plus de détails sur KSPP sont
disponibles sur le wiki du projet .
STACKLEAK est présent en tant que PAX_MEMORY_STACKLEAK dans le correctif grsecurity / PaX. Cependant, le correctif grsecurity / PaX a cessé d'être distribué gratuitement depuis avril 2017. Par conséquent, l'apparition de STACKLEAK dans le noyau vanilla serait précieuse pour les utilisateurs Linux ayant des exigences accrues en matière de sécurité des informations.
Ordre de travail:
- sélectionnez STACKLEAK dans le patch grsecurity / PaX,
- étudiez soigneusement le code et formez un patch,
- envoyer à LKML, obtenir des commentaires, améliorer, répéter à nouveau avant d'être accepté dans la ligne principale.
Au moment de la rédaction (25 septembre 2018), la
version 15 d'une série de correctifs a été envoyée. Il contient une partie indépendante de l'architecture et du code pour x86_64 et x86_32. Le support STACKLEAK pour arm64, développé par Laura Abbott de Red Hat, a déjà réussi à entrer dans le noyau vanilla 4.19.
STACKLEAK: fonctionnalités de sécurité
Effacement des informations résiduelles dans la pile du noyau
Cette mesure réduit les informations utiles que certaines fuites de la cheminée nucléaire vers l'espace utilisateur peuvent produire.
Un exemple de fuite d'informations de la pile du noyau est présenté à la figure 1.
Schéma 1.Cependant, les fuites de ce type deviennent inutiles si, à la fin d'un appel système, la partie utilisée de la pile du noyau est remplie avec une valeur fixe (figure 2).

Schéma 2.
Par conséquent, STACKLEAK bloque certaines attaques contre des variables non initialisées dans la pile du noyau. Exemples de telles vulnérabilités: CVE-2017-17712, CVE-2010-2963. Nous pouvons trouver une description de la méthodologie d'exploitation de la vulnérabilité CVE-2010-2963
dans un article de Kees Cook.
L'essence de l'attaque d'une variable non initialisée dans la pile du noyau est illustrée à la figure 3.
Schéma 3.STACKLEAK bloque les attaques de ce type, car la valeur qui remplit la pile nucléaire à la fin d'un appel système indique une zone inutilisée dans l'espace d'adressage virtuel (figure 4).
Schéma 4.Une limitation importante est que STACKLEAK ne protège pas contre les attaques similaires effectuées dans un seul appel système.
Détection de débordement de pile de noyau dans le noyau
Dans le noyau vanilla (ligne principale du noyau Linux) STACKLEAK est efficace contre le débordement de profondeur de pile du noyau uniquement en conjonction avec CONFIG_THREAD_INFO_IN_TASK et CONFIG_VMAP_STACK. Ces deux mesures sont mises en œuvre par Andy Lutomirski.
La version la plus simple de l'exploitation de ce type de vulnérabilité est illustrée à la figure 5.
Schéma 5.L'écrasement de certains champs dans la structure thread_info au bas de la pile nucléaire peut augmenter les privilèges du processus. Cependant, lorsque l'option CONFIG_THREAD_INFO_IN_TASK est activée, cette structure est supprimée de la pile nucléaire, ce qui élimine la méthode décrite d'exploiter la vulnérabilité.
Une version plus avancée de cette attaque consiste à écraser les données dans une région de mémoire voisine en sortant de la bordure de la pile. Plus sur cette approche:
Ce type d'attaque se reflète dans la figure 6.
Schéma 6.Dans ce cas, la protection est CONFIG_VMAP_STACK. Lorsque cette option est activée, une page mémoire spéciale (page de garde) est placée à côté de la pile nucléaire, dont l'accès conduit à une exception (figure 7).
Schéma 7.Enfin, l'option la plus intéressante de déborder la pile en profondeur est une attaque comme Stack Clash. L'idée a été
avancée par Gael Delalleau en 2005.
En 2017, des chercheurs de la société Qualys l'ont repensé,
appelant cette technique Stack Clash. Le fait est qu'il existe un moyen de sauter par-dessus la page de garde et d'écraser les données d'une région de mémoire voisine (figure 8). Cela se fait à l'aide d'un tableau de longueur variable (VLA), dont la taille est contrôlée par l'attaquant.
Schéma 8.Pour plus d'informations sur STACKLEAK et Stack Clash,
consultez le blog grsecurity .
Comment STACKLEAK se protège-t-il contre Stack Clash dans la pile nucléaire? Avant chaque appel à alloca (), une vérification approfondie du dépassement de pile est effectuée. Voici le code correspondant de la version 14 de la série de correctifs:
void __used stackleak_check_alloca(unsigned long size) { unsigned long sp = (unsigned long)&sp; struct stack_info stack_info = {0}; unsigned long visit_mask = 0; unsigned long stack_left; BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask)); stack_left = sp - (unsigned long)stack_info.begin; if (size >= stack_left) { #if !defined(CONFIG_VMAP_STACK) && defined(CONFIG_SCHED_STACK_END_CHECK) panic("alloca() over the kernel stack boundary\n"); #else BUG(); #endif } }
Cependant, cette fonctionnalité a été exclue de la version 15. Cela était principalement dû à l'
interdiction controversée de Linus Torvalds d'utiliser BUG_ON () dans les correctifs de sécurité du noyau Linux.
En outre, la 9e version de la série de correctifs a conduit à une discussion, à la suite de laquelle il a été décidé d'éliminer tous les tableaux de variables du noyau principal. Une quinzaine de développeurs ont été impliqués dans ce travail, et il sera bientôt
terminé .
Impact sur les performances de STACKLEAK
Je donne les résultats des tests de performances sur x86_64. Équipement: Intel Core i7-4770, 16 Go de RAM.
Test n ° 1, attractif: construire un noyau Linux sur un seul cœur de processeur
Essai n ° 2, sans attrait:
Par conséquent, l'effet de STACKLEAK sur les performances du système dépend du type de charge. En particulier, un grand nombre d'appels système courts augmentent les frais généraux. T.O. Les performances de STACKLEAK doivent être évaluées pour la charge planifiée avant la production.
Périphérique interne STACKLEAK
STACKLEAK comprend:
- Le code qui efface la pile du noyau à la fin de l'appel système (écrit à l'origine dans l'assembleur),
- Plugin GCC pour la compilation instrumentale du code du noyau.
L'effacement de la pile du noyau se fait dans la fonction stackleak_erase (). Cette fonction est remplie avant de retourner dans l'espace utilisateur après un appel système. Le STACKLEAK_POISON (-0xBEEF) est écrit dans la partie utilisée de la pile de threads. La variable lower_stack, constamment mise à jour dans stackleak_track_stack (), pointe vers le point de départ du nettoyage.
Les étapes de stackleak_erase () sont reflétées dans les schémas 9 et 10.
Schéma 9.
Schéma 10.T.O. stackleak_erase () efface uniquement la partie utilisée de la pile nucléaire. C'est pourquoi STACKLEAK est si rapide. Et si vous effacez les 16 Ko de la pile du noyau sur x86_64 à la fin de chaque appel système, hackbench affiche une baisse de performances de 40%.
L'instrumentation du code du noyau au stade de la compilation est effectuée dans le plugin STACKLEAK GCC.
Les plugins GCC sont des modules téléchargeables spécifiques au projet pour le compilateur GCC. Ils enregistrent de nouvelles passes avec le GCC Pass Manager, fournissant des rappels pour ces passes.
Ainsi, pour une opération STACKLEAK à part entière, les appels à stackleak_track_stack () sont insérés dans le code des fonctions avec un grand cadre de pile. De plus, avant chaque alloca (), un appel à stackleak_check_alloca () est déjà inséré, et après cela, un appel à stackleak_track_stack () est inséré.
Comme déjà mentionné, dans la version 15 de la série de correctifs, l'insertion d'appels à stackleak_check_alloca () a été exclue du plugin GCC.
Chemin dans la ligne principale du noyau Linux
Le chemin STACKLEAK dans la ligne principale est très long et difficile (figure 11).
Schéma 11. Progrès de l'implémentation de STACKLEAK dans la ligne principale du noyau Linux.En avril 2017, les créateurs de grsecurity ont fermé leurs correctifs pour la communauté, commençant à les distribuer uniquement sur une base commerciale. En mai 2017, j'ai décidé de prendre en charge l'introduction de STACKLEAK dans le noyau vanille. Ainsi commença un voyage de plus d'un an. La société Positive Technologies, dans laquelle je travaille, me donne l'opportunité de m'acquitter de cette tâche pendant une partie de mon temps de travail. Mais en gros, j'y passe du temps «libre».
Depuis mai dernier, ma série de patchs a subi plusieurs révisions, a subi des changements importants, a été critiquée deux fois par Linus Torvalds. Je voulais quitter tout cela plusieurs fois. Mais à un certain moment, il y avait une ferme volonté d'atteindre la fin. Au moment de la rédaction (25 septembre 2018), la 15e version de la série de correctifs est dans la branche linux-next, répond à toutes les exigences énoncées de Linus et est prête pour la fenêtre de fusion du noyau 4.20 / 5.0.
Il y a un mois, j'ai fait un exposé sur ce travail sur le Linux Security Summit. Je fournis des liens vers des
diapositives et des
vidéos :
Conclusion
STACKLEAK est une fonction de sécurité du noyau Linux très utile qui bloque l'exploitation de plusieurs types de vulnérabilités à la fois. De plus, l'auteur original de PaX Team a pu le rendre rapide et beau en ingénierie. Par conséquent, l'apparition de STACKLEAK dans le noyau vanilla serait précieuse pour les utilisateurs Linux ayant des exigences accrues en matière de sécurité des informations. De plus, les travaux dans ce sens attirent l'attention de la communauté des développeurs Linux sur les outils d'autodéfense du noyau.
PS
STACKLEAK a finalement été adopté par le noyau Linux 4.20:
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2d6bb6adb714b133db92ccd4bfc9c20f75f71f3fLes architectures prises en charge sont x86_64, x86_32 et arm64.
De plus, des travaux ont été effectués pour éliminer les tableaux de longueur variable du code du noyau Linux. L'avertissement du compilateur Gcc "-Wvla" est inclus dans la version 4.20 du noyau:
lkml.org/lkml/2018/10/28/189