Un débordement de pile est-il détecté par le matériel ou le logiciel?

26

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?

gilianzz
la source
Je dirais du matériel, à travers des défauts MMU sur la plupart des CPU. x86 en mode 32bits avait une segmentation en plus de la pagination, et le "segment de pile" est associé, comme les segments Code, Data, Ext ... avec à la fois une adresse de base et une taille. Tout accès en dehors de cette plage déclencherait un défaut.
TEMLIB

Réponses:

25

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.

Gilles 'SO- arrête d'être méchant'
la source
4
Je n'appellerais pas l'accès au tableau hors limites un débordement de pile, même si le tableau est sur la pile. C'est juste un cas particulier de débordement de tampon.
CodesInChaos
Ne pas allouer aux éléments de pile principaux qui sont référencés par rapport à un pointeur non pile / trame ou à un décalage non constant éviterait les débordements de pile traditionnels. L'utilisation d'une pile d'adresses de retour distincte (ou d'une pile de déversement RA / registre comme Itanium) réduirait au moins considérablement les possibilités de programmation orientée retour.
Paul A. Clayton
L'accès hors des limites est plus correctement appelé un dépassement , pas un débordement.
Ben Voigt
3
@ awesomebing1 toutes les plateformes ne détectent pas les débordements de pile. Vous pourriez juste finir par écraser tout ce qui se trouve après la pile (similaire à tout autre débordement de tampon).
user253751
1
@CodesInChaos, parfois les débordements de tampon dans les tampons alloués à la pile sont appelés "débordements de pile" (pour faire court). Certes, cette terminologie peut être un peu déroutante sans contexte.
DW