232 votes

Comment est-il dangereux pour accéder à un tableau hors des limites ?

Quel est le danger d'accéder à un tableau en dehors de ses limites (en C)? Il peut parfois arriver que j'ai lu de l'extérieur de la matrice (maintenant, je comprends que je ne puis accéder à la mémoire utilisée par certaines autres parties de mon programme ou même au-delà) ou je suis en train de mettre une valeur à un indice en dehors de la matrice. Le programme plante parfois, mais parfois seulement fonctionne, seulement de donner des résultats inattendus.

Maintenant ce que j'aimerais savoir, quel est le danger d'-ce vraiment? Si elle endommage mon programme, il n'est pas si mauvais. Si d'autre part il se casse quelque chose en dehors de mon programme, car j'ai réussi à accéder à certains totalement sans rapport avec la mémoire, alors il est très mauvais, j'imagine. J'ai lu beaucoup de 'tout peut arriver', 'la segmentation peut-être le moins mauvais problème', 'votre disque dur peut virer au rose et les licornes peut-être chanter sous votre fenêtre", qui est tout beau, mais ce qui est vraiment le danger?

Mes questions:

  1. Peut lire les valeurs de façon à l'extérieur de la matrice endommager quoi que ce soit en dehors de mon programme? J'imagine juste de regarder les choses ne ne rien changer, ou serait-il par exemple de modifier le " dernier moment ouvert attribut d'un fichier il m'est arrivé d'atteindre?
  2. Pouvez les valeurs de réglage chemin à l'extérieur de la matrice des dommages de quelque chose en dehors de mon programme? À partir de ce stackoverflow question , je suppose que c'est possible d'accéder à toute l'emplacement de la mémoire, qu'il n'existe aucune garantie de sécurité.
  3. J'ai mon petit programmes à partir de XCode. Ne que fournir une certaine protection supplémentaire autour de mon programme où il ne peut pas atteindre l'extérieur de sa propre mémoire? Peut-il nuire à XCode?
  4. Des recommandations sur la façon de gérer mon intrinsèquement code bogué en toute sécurité?

J'utilise OSX 10.7, Xcode 4.6

C'est ma première Stackoverflow question. J'ai pris le temps de lire autant que je le pouvais sur le sujet, mais j'ai probablement raté beaucoup de ressources. Laissez-moi savoir si vous vous sentez que je n'ai pas assez de recherche et/ou voyez-vous d'autres problèmes avec cette question.

130voto

Keith Thompson Points 85120

Aussi loin que l'ISO C standard (la définition officielle de la langue), l'accès à un tableau en dehors de ses limites a "un comportement non défini". Le sens littéral de ce qui est:

problème, lors de l'utilisation d'un non-compatibles ou erronées programme de construction ou de des données erronées, pour lequel la présente Norme Internationale n'impose aucune exigences

Un non-normatif remarque s'étend sur ceci:

Possible un comportement indéfini plages d'ignorer la situation complètement avec des résultats imprévisibles, à se comporter lors de la traduction ou de l'exécution du programme dans documenté de façon caractéristique de l' de l'environnement (avec ou sans émission d'un message de diagnostic), à cessation de la traduction ou de l'exécution (avec l'émission d'un message de diagnostic).

Donc, c'est la théorie. Quelle est la réalité?

Dans le "meilleur" des cas, vous aurez accès à un morceau de la mémoire qui soit la propriété de votre programme en cours d'exécution (ce qui pourrait causer à votre programme à mal se conduire), ou c'est pas détenue par votre programme en cours d'exécution (ce qui sera probablement la cause de votre programme de collision avec quelque chose comme une erreur de segmentation). Ou vous pourriez tenter d'écrire dans la mémoire de votre programme est propriétaire, mais c'est marqué en lecture seule; ce sera probablement également faire planter le programme.

C'est en supposant que votre programme est en cours d'exécution dans un système d'exploitation qui tente de protéger simultanément les processus en cours d'exécution les uns des autres. Si votre code est en cours d'exécution sur le "bare metal", de dire si elle fait partie d'un noyau de système d'exploitation ou d'un système embarqué, alors il n'y a pas une telle protection; comportement anormal de votre code est ce qui était censé fournir une protection. Dans ce cas, les possibilités pour les dommages sont beaucoup plus importantes, y compris, dans certains cas, les dommages au matériel (ou à des choses ou des personnes à proximité).

Même dans un système d'exploitation sécurisé de l'environnement, les protections ne sont pas toujours à 100%. Il y a des bogues de système d'exploitation qui permettent non privilégié des programmes pour obtenir la racine (administrative) de l'accès, par exemple. Même avec des privilèges d'utilisateur, d'un mauvais fonctionnement du programme peut consomment trop de ressources (CPU, mémoire, disque), éventuellement de ramener l'ensemble du système. Beaucoup de logiciels malveillants (virus, etc.) les exploits des dépassements de mémoire tampon pour obtenir un accès non autorisé au système.

(Un exemple historique: j'ai entendu dire que sur certains vieux systèmes à base de mémoire, à plusieurs reprises l'accès à un seul emplacement de mémoire dans une boucle serrée, pourrait littéralement cause que partie de la mémoire à fondre. D'autres possibilités incluent la destruction d'un écran CRT, et en déplaçant la tête de lecture/écriture du disque dur avec l'harmonique de la fréquence de l'armoire, à l'origine de marcher à travers une table et de tomber sur le sol.)

Et il y a toujours Skynet à s'inquiéter.

La ligne de fond est la suivante: si vous pouviez écrire un programme pour faire quelque chose de mal délibérément, c'est au moins théoriquement possible qu'un buggy programme pourrait faire la même chose accidentellement.

Dans la pratique, il est très peu probable que votre buggy programme en cours d'exécution sur un MacOS X système est en train de faire quelque chose de plus sérieux que de se bloquer. Mais il n'est pas possible de complètement éviter buggy code de faire des choses vraiment mauvaises.

26voto

trumpetlicks Points 5830

En général, les Systèmes d'Exploitation d'aujourd'hui (les plus populaires de toute façon) exécuter toutes les applications dans la mémoire protégée régions à l'aide d'un gestionnaire de mémoire virtuelle. Il s'avère qu'il n'est pas très FACILE (par exemple) à simplement lire ou écrire à un endroit qui existe dans l'espace RÉEL à l'extérieur de la région(s) qui vous ont été attribués et / ou d'affecter à votre processus.

Réponses directes:

1) la Lecture ne sera presque jamais directement les dommages d'un autre processus, mais il peut indirectement des dommages à un processus si il vous arrive de lire une valeur de CLÉ utilisée pour chiffrer, déchiffrer, ou de valider un programme / processus. La lecture en dehors des limites peut avoir un peu indésirables ou inattendus affecte votre code si vous êtes à la prise de décisions basées sur les données que vous lisez

2) La seule façon pour votre pourrait ENDOMMAGER vraiment quelque chose par écrit à un emplacement accessible par une adresse mémoire est si l'adresse mémoire que vous écrivez est en fait un matériel de registre (un endroit qui en fait n'est pas pour le stockage de données, mais pour le contrôle de certaines pièces de matériel) n'est pas une RAM emplacement. Dans tous fait, vous avez toujours l'habitude normalement endommager quelque chose, à moins que vous écrivez quelque programmables une seule fois l'emplacement qui n'est pas ré-inscriptible (ou quelque chose du genre).

3) en Général qui s'exécute dans le débogueur exécute le code en mode de débogage. L'exécution en mode debug, ça a TENDANCE à (mais pas toujours) d'arrêter votre code plus rapide lorsque vous avez fait quelque chose de considéré comme hors de la pratique, ou carrément illégales.

4) ne Jamais utiliser les macros, l'utilisation des structures de données qui ont déjà des index de tableau des limites de la vérification intégrée, etc....

SUPPLÉMENTAIRES Je dois ajouter que l'information ci-dessus est vraiment seulement pour les systèmes utilisant un système d'exploitation avec protection de la mémoire de windows. Si l'écriture de code pour un système embarqué ou même un système utilisant un système d'exploitation (en temps réel ou d'autres) qui n'ont pas de protection de la mémoire windows (ou virtuel adressée windows) que l'on doit pratiquer beaucoup plus de prudence dans la lecture et l'écriture de la mémoire. Aussi, dans ces cas, SÛR et SÉCURISÉ pratiques de codage devrait toujours être utilisé pour éviter les problèmes de sécurité.

11voto

che Points 6899

Ne pas vérifier les limites peuvent conduire à des à laide des effets secondaires, y compris des trous de sécurité. L'un des moches est l'exécution de code arbitraire. Dans l'exemple classique: si vous disposez d'un tableau de taille fixe, et d'utiliser strcpy() pour mettre une chaîne de là, l'utilisateur peut vous donner une chaîne de dépassements de la mémoire tampon et écrase les autres emplacements de la mémoire, y compris le code de l'adresse où le CPU doit retourner lors de votre fonction se termine.

Ce qui signifie que vos utilisateurs puissent vous envoyer une chaîne de caractères qui sera la cause de votre programme, essentiellement appel exec("/bin/sh"), ce qui va le transformer en coquille, l'exécution de tout ce qu'il veut sur votre système, y compris la récolte de l'ensemble de vos données et de transformer votre machine en botnet nœud.

Voir casser La Pile Pour le Plaisir Et le Profit pour plus de détails sur la façon dont cela peut être fait.

9voto

Udo Klein Points 3038

Vous écrivez:

J'ai lu beaucoup de 'tout peut arriver', 'la segmentation peut être le moins grave problème", " votre disque dur peut virer au rose et des licornes qui pourrait chanter sous votre fenêtre", qui est tout beau, mais ce qui est vraiment le danger?

Permet de mettre de cette façon: charger une arme à feu. Point à l'extérieur de la fenêtre sans viser et tirer. Quel est le danger?

Le problème est que vous ne connaissez pas. Si votre code remplace quelque chose qui bloque votre programme, vous êtes bien parce qu'il va l'arrêter dans un état. Toutefois, si elle ne tombe pas en panne alors les problèmes commencent à surgir. Les ressources qui sont sous le contrôle de votre programme et que pourrait-on faire pour eux? Les ressources qui pourrait passer sous le contrôle de votre programme et que pourrait-on faire pour eux? Je connais au moins un problème majeur qui a été causé par un tel débordement. La question était dans un apparemment sans signification statistique de la fonction qui a foiré certains sans rapport avec le tableau de conversion pour une base de données de production. Le résultat était certains très coûteux de nettoyage par la suite. En fait, il aurait été beaucoup moins cher et plus facile à gérer si cette question ont formaté les disques durs ... avec d'autres mots: rose licornes peut être moins de problème.

L'idée que votre système d'exploitation permettra de vous protéger est optimiste. Si possible, essayez d'éviter d'écrire en dehors des limites.

7voto

mikyra Points 3595

Pas l'exécution de votre programme en tant que root ou de tout autre utilisateur privilégié de ne pas nuire à tout de votre système, alors ce pourrait être une bonne idée.

Par l'écriture de données à un emplacement de mémoire vive, vous ne serez pas directement les "dommages" tout autre programme en cours d'exécution sur votre ordinateur comme chaque processus s'exécute dans son propre espace mémoire.

Si vous essayez d'accéder à toute la mémoire allouée à votre processus le système d'exploitation va arrêter votre programme à partir de l'exécution avec une erreur de segmentation.

Donc, directement (sans exécuter en tant que root et accéder directement aux fichiers comme /dev/mem) il n'y a pas de danger que votre programme va interférer avec un autre programme en cours d'exécution sur votre système d'exploitation.

Néanmoins - et c'est probablement ce que vous avez entendu parler en termes de danger - en aveugle en écriture aléatoire de données aléatoires emplacements de mémoire par accident bien sûr que vous pouvez endommager quoi que ce soit, vous êtes en mesure de dommages.

Par exemple, votre programme voudrez peut-être supprimer un fichier spécifique donnée par un nom de fichier stocké quelque part dans votre programme. Si par hasard vous venez de remplacer l'emplacement où le nom de fichier sont stockées vous pouvez supprimer un de très différent de fichier à la place.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X