Est-ce la tâche du logiciel (système d'exploitation) de détecter les débordements de pile ou un débordement de pile est-il détecté dans le matériel, provoquant une exception dans le CPU?
Est-ce la tâche du logiciel (système d'exploitation) de détecter les débordements de pile ou un débordement de pile est-il détecté dans le matériel, provoquant une exception dans le CPU?
Réponses:
Il peut s'agir de logiciels ou de matériel, ou des deux, ou aucun.
Il existe deux types de débordements: le débordement lors de l'agrandissement de la pile (lors de la saisie d'une fonction) et le débordement lors de l'accès à un tableau sur la pile. Les débordements lors de l'agrandissement de la pile peuvent être détectés en effectuant une vérification des limites à l'entrée de la fonction, pour vérifier qu'il y a suffisamment de place (et signaler une erreur ou agrandir la pile s'il n'y en a pas). Les débordements lors de l'accès à un tableau sur la pile ne sont un problème que dans les langages de bas niveau qui ne vérifient pas les limites du tableau; la solution consiste à vérifier les limites du tableau.
Ces approches logicielles ont l'avantage de fonctionner de manière totalement fiable: vous pouvez être sûr que tout débordement de pile sera détecté. Leur inconvénient est qu'ils augmentent la taille du code et le temps d'exécution. Le matériel peut vous aider en fournissant une méthode pour détecter la plupart des débordements sans frais tant qu'aucun débordement ne se produit. Sur une architecture avec une MMU ¹, l'environnement d'exécution peut organiser le mappage de la pile sur une limite de page, la page suivante restant non mappée.
+---------------+---------------+---------------+---------------+
| stack | unmapped | other stuff |
| ----> direction of growth | | |
+---------------+---------------+---------------+---------------+
^ ^ ^ ^ ^ page boundaries
De cette façon, si le logiciel tente d'accéder aux données au-delà de la limite de la page (que ce soit parce que le pointeur de pile a dépassé la limite ou parce que l'accès au tableau est hors limites et au-delà de la limite), il provoquera une erreur en accédant à une zone non mappée . Cela ne se produit que si le débordement est suffisamment petit: si le montant du débordement est trop important, le programme peut finir par accéder à d'autres éléments de l'autre côté de l'espace dans l'espace d'adressage.
L'inconvénient de l'approche matérielle est qu'elle n'est pas entièrement fiable car un débordement important peut ne pas être détecté et qu'elle ne détecte pas les débordements de baies qui restent dans l'espace adressable.
Pour détecter les débordements de tableau, une autre technique logicielle est un canari : mettez une valeur spéciale en haut de la pile ou entre les trames, et vérifiez que la valeur du canari n'a pas changé au retour de la fonction. Il s'agit également d'une technique imparfaite, car le débordement peut éviter complètement le canari ou peut ne pas être détecté car la valeur du canari a été restaurée au moment de la vérification. Néanmoins, il est utile de rendre plus difficile l'exploitation de certaines failles de sécurité.
Le moyen le plus sûr et le moins cher d'éviter les débordements de pile est de calculer la quantité de pile dont le programme aura besoin avant de commencer à l'exécuter, par analyse statique. Cependant, cela n'est pas toujours pratique: la quantité de pile nécessaire à un programme est indécidable en général et dépend des données manipulées par le programme.
¹ Le même principe peut également être appliqué avec juste un MPU, ou sans protection de mémoire s'il y a un seul thread dont la pile est au bord des mappages physiques existants.