Qu'est-ce qui empêche un programme d'assemblage de planter le système d'exploitation? [fermé]

18

Tout d'abord, je suis un débutant, donc si cette question semble idiote, veuillez signaler les hypothèses incorrectes.

D'après ce que je comprends, le travail d'un système d'exploitation est de gérer le matériel et les logiciels qui s'exécutent sur le système d'exploitation. De plus, d'après ce que je comprends, les programmes d'assemblage permettent de contrôler le matériel presque directement. Dans un programme d'assemblage, on peut lire et écrire des données dans des registres, et lire et écrire des données dans la RAM.

Compte tenu de cette liberté de jouer avec les registres et la RAM, ne serait-il pas possible pour les programmes d'assemblage d'affecter le système d'exploitation? Supposons qu'un système d'exploitation utilise le registre A pour stocker des informations cruciales, et supposons que j'exécute un programme assemblé sur ce système d'exploitation. Si le programme écrit avec succès des fichiers indésirables dans le registre A, le système d'exploitation sera sûrement affecté.

Des questions:

  1. Est-il possible de jouer avec le registre A de la manière décrite ci-dessus?

  2. Sinon, qu'est-ce qui empêche les programmes d'assemblage de modifier les registres utilisés par le système d'exploitation?

Flux
la source
13
programmeurs intelligents ...
Tony Stewart Sunnyskyguy EE75
Il existe de nombreuses architectures informatiques aujourd'hui et dans le passé, ainsi que de nombreux systèmes d'exploitation ont été développés. De quelle architecture / OS parlez-vous exactement? Sur certaines (anciennes) architectures, il n'était pas possible d'arrêter le programme de ce qu'il faisait après le démarrage, c'est exact. Mais le matériel / OS moderne a intégré des outils matériels qui ne donnent que la partie de la mémoire pour le programme en mode "normal" (pas superutilisateur), et il ne peut pas accéder à la mémoire en dehors de cette limite. Les registres sont gratuits à utiliser, car le système d'exploitation ne stocke aucune information utile dans les registres, juste dans la mémoire / sur le disque.
cyclone125
2
Dans un microprocesseur, votre programme s'exécute en "mode utilisateur", les systèmes d'exploitation s'exécutent en "mode système". Si un programme en mode utilisateur exécutait une instruction d'arrêt, par exemple, la machine ne s'arrêterait pas. L'arrêt serait piégé et le système d'exploitation invoqué. En ce qui concerne la RAM, le système d'exploitation mettrait en place un environnement pour le programme en mode utilisateur afin que, via le matériel de gestion de la mémoire, ce que le programme utilisateur considère comme l'adresse RAM X ne soit pas vraiment l'adresse RAM X.
George White
1
@flux J'ai mis à jour mon commentaire. La réponse serait: il n'y a pas de réponse "générale" à votre question, car il y a / il y avait différentes architectures informatiques / OS. Cela peut être de différentes manières.
cyclone125
2
... Il y a longtemps, j'écrivais en code machine brut. Ouais ha !!! :-)
Russell McMahon

Réponses:

33

Au final, tous les programmes sont du code machine, que la langue source soit l'assembleur ou un langage de haut niveau.

L'important est qu'il existe des mécanismes matériels qui limitent ce qu'un processus donné peut faire, y compris "jouer avec" les registres qui pourraient affecter d'autres programmes ou le système d'exploitation lui-même.

Cela a commencé par une simple distinction entre les modes de fonctionnement «utilisateur» et «superviseur», et a depuis évolué vers une architecture de sécurité avec plusieurs «anneaux» de privilèges.


Voici un exemple très générique pour le rendre un peu plus concret:

  • En "mode utilisateur", un processus ne peut pas accéder à la mémoire qui n'a pas été affectée à son ID de processus. La mémoire affectée à d'autres processus et le système d'exploitation lui-même sont bloqués. Cela inclut les valeurs des registres utilisés par ces autres processus. Ceci est appliqué par le matériel MMU.

  • Par conséquent, en "mode utilisateur", un processus ne peut pas accéder aux registres de contrôle MMU.

  • Et évidemment, en "mode utilisateur", un processus ne peut pas changer le mode en "mode superviseur" sauf via un mécanisme très bien défini qui implique d'appeler une fonction du système d'exploitation.

Le système d'exploitation prend le contrôle si le processus tente d'enfreindre l'une de ces règles. Une fois que cela se produit, le système d'exploitation peut simplement arrêter le processus incriminé, sans jamais exécuter plus de ses instructions.

Dave Tweed
la source
2
Si je comprends bien, ce que vous dites est: Certains processeurs ont le "mode utilisateur" et le "mode superviseur". Le système d'exploitation fonctionne en "mode superviseur" et met le processeur en "mode utilisateur" pour exécuter mon programme d'assemblage fictif. En "mode utilisateur", il existe des registres et des adresses RAM auxquels le programme d'assemblage ne peut pas accéder en raison de la conception délibérée du matériel.
Flux
3
Fondamentalement, cette réponse décrit des architectures modernes «de type i386» avec MMU et mode protégé. Mais pour être vrai, il existe de nombreuses architectures anciennes (i8080, MOS 6502, etc.) ainsi que des architectures modernes plus simples (AVR, ARM Cortex-M, etc.) qui ne disposent pas de ces fonctionnalités et si un type de système d'exploitation est utilisé (par exemple, les anciens CP / M, FreeRTOS moderne, ChibiOS etc.) rien ne peut arrêter le programme de ce qu'il fait.
cyclone125
2
@Flux Les architectures i386 (et supérieures) fournissent des détails à apprendre. L'architecture x86 a non seulement des adresses mémoire qui peuvent être protégées, mais aussi des adresses d'E / S. (Il existe différentes instructions pour l'accès à la mémoire et l'accès aux E / S.) Il y a trois adresses mémoire dans l'i386 +. L'adresse segmentée / basée sur le sélecteur utilise un registre de sélecteur qui fait référence à une entrée de table (GDT ou LDT) pour mapper la paire en une seule adresse linéaire 32 bits. Les tables de pagination traduisent ensuite l'adresse linéaire 32 bits en une adresse physique 36 bits (P-II). Une protection existe aux deux étapes de la traduction.
jonk
4
@flux votre résumé est correct. Un programme dans un système de mémoire protégé avec un système d'exploitation multitâche approprié ne devrait pas être en mesure de bloquer le système avec un flux d'instructions. Même les invalides - ceux-ci se retrouvent dans un gestionnaire spécial.
pjc50
Même s'il existe plusieurs anneaux (en x86 au moins), il est très, très rare que plus de deux soient effectivement utilisés.
forêt
10

De nombreux systèmes d'exploitation multitâches utilisent une structure de données appelée Process Control Block (PCB) pour résoudre le problème d'écrasement du registre. Lorsque vous exécutez votre code, le système d'exploitation crée un nouveau processus pour en garder la trace. Le PCB contient des informations sur votre processus et l'espace alloué pour contenir le contenu du registre. Disons que le processus A est actuellement en cours d'exécution sur le processeur et que votre code est en cours B. Que se passe-t-il lorsque vous exécutez votre code va quelque chose comme ça:

  1. Les données d'état du processus A (contenu du registre, compteur de programmes, etc.) sont copiées dans son PCB.

  2. Les données d'état du processus B sont copiées de son PCB dans les registres CPU

  3. Le processus B s'exécute sur le processeur jusqu'à ce qu'il se termine ou soit préempté

  4. Les données d'état du processus B sont recopiées dans son PCB

  5. Les données d'état du processus A sont recopiées dans le CPU et il continue de fonctionner

Si le système d'exploitation s'exécute en tant que processus A, vous pouvez voir comment enregistrer ses registres avant l'exécution de votre programme, puis les recopier dans le processeur une fois votre programme terminé, empêche les programmes utilisateur de jouer avec ce qui se passe dans les autres processus.

Pour éviter que les processus utilisateur écrivent sur les données du système d'exploitation en mémoire, la plupart des plates-formes utilisent la segmentation de la mémoire. Fondamentalement, en utilisant la mémoire virtuelle, l'espace d'adressage qu'un processus voit peut être mappé à n'importe quelle plage arbitraire d'adresses physiques. Tant que les espaces de mémoire physique des processus ne se chevauchent pas, il est impossible pour un processus d'écraser les données d'un autre.

Bien sûr, différents systèmes d'exploitation font les choses différemment, donc cela ne s'applique pas dans tous les cas. En outre, sur la plupart des plates-formes, les processus du système d'exploitation s'exécutent dans un mode différent des processus utilisateur et il existe certaines subtilités.

jtst
la source
4

Cela dépend de quelle plateforme vous parlez.

  • Sur un processeur plus basique, le processeur exécute simplement les instructions que le programme lui demande d'exécuter.

  • Sur un processeur plus sophistiqué, il existe (au moins) deux modes. Dans un mode, le processeur fait tout ce que le programme lui dit de faire. Dans l'autre mode, le processeur lui-même refuse d'exécuter certaines instructions.

Qu'est-ce qui empêche un programme de planter tout le système? Avec le premier type de processeur, la réponse est "rien". Avec un processeur de base, un seul programme escroc peut en effet planter l'ensemble du système. Tous les premiers ordinateurs personnels 8 bits et la plupart des ordinateurs 16 bits entrent dans cette catégorie.

Sur un PC moderne, le processeur dispose d'un matériel de "protection". Fondamentalement, le système d'exploitation s'exécute dans un mode spécial qui lui permet de faire quoi que ce soit, tandis que les programmes normaux s'exécutent dans un mode où le processeur autorise uniquement certaines actions (en fonction des paramètres que le système d'exploitation a configurés sur le processeur). Des trucs comme accéder uniquement à certains registres, ou accéder uniquement à des plages de mémoire particulières.

De toute évidence, permettre à un seul programme malveillant de planter le système entier est mauvais. (Il y a également de graves implications pour la sécurité à permettre à un programme malveillant d'accéder aux données qu'il souhaite.) Pour éviter cela, vous avez besoin de deux choses:

  1. Un processeur qui dispose en fait d'un matériel de protection (c'est-à-dire qu'il peut être configuré pour refuser d'exécuter certaines instructions).

  2. Un système d'exploitation qui utilise réellement ces fonctionnalités pour se protéger. (Ce n'est pas bon d'avoir une puce avec des circuits de protection si le système d'exploitation ne l'utilise jamais!)

À peu près n'importe quel OS de bureau moderne que vous pouvez nommer (Windows, Linux, Mac OS, BSD ...) c'est un OS en mode protégé fonctionnant sur un processeur avec un matériel de protection. Si vous faites du développement intégré sur un microcontrôleur 8 bits, cela n'a probablement pas de matériel de protection. (Ou n'importe quel OS, d'ailleurs ...)

MathematicalOrchid
la source
1

Q. Qu'est-ce qui empêche un programme d'assemblage de planter le système d'exploitation?

R. Rien.

Cependant, beaucoup de programmeurs très intelligents ont fait de leur mieux au fil des ans pour le rendre de plus en plus difficile. Malheureusement, pour chaque programmeur intelligent, il y en a beaucoup, beaucoup d'autres qui, entre eux, sont plus créatifs, plus ambitieux et parfois juste plus chanceux que les plus intelligents. Chaque fois qu'un programmeur intelligent dit que personne ne devrait, ne ferait ou ne pourrait faire quelque chose, quelqu'un trouverait un moyen de le faire. Microsoft Windows (à titre d'exemple) existe depuis près de 35 ans et nous avons toujours des BSoD (Blue Screens of Death), qui ne sont que des instructions qui ont fait planter le système d'exploitation.

Commençons par un peu de terminologie. Tout ce qui s'exécute sur un ordinateur le fait en code machine. Le bit qui lit les frappes ou le mouvement du pointeur de la souris, le bit qui change la couleur d'un pixel à l'écran ou lit un octet dans un fichier et le bit qui calcule si votre balle a frappé le méchant ou le bit qui décide si votre demande de carte de crédit est acceptée, toutes sont exécutées comme une séquence d'instructions de code machine. Certains travaux sont si courants et sont effectués si souvent qu'il est logique d'assembler les instructions nécessaires pour les faire et de faire en sorte que tout le monde utilise cet assemblage. Le tas de ces emplois qui permettent ou aident les autres à utiliser l'ordinateur ont tendance à être appelés le système d'exploitation, mais il n'y a rien de fondamentalement différent entre eux et les autres programmes. Ce ne sont que des séquences d'instructions de code machine.

Ce qui rend les systèmes d'exploitation plus compliqués (et donc sujets à planter), c'est qu'ils doivent tenir compte de choses auxquelles vous n'avez normalement pas à penser. Prenons l'exemple des tâches les plus simples. Je veux écrire un message à la fin d'un fichier. Dans une langue de haut niveau, vous écririez quelque chose comme:

  with open("myFile.txt", "w+") as f:
      # do some really clever things
      f.write("Goodbye cruel world!")

Permet d'ignorer tous les détails sur la façon dont les états physiques sont accédés et modifiés ou comment ils sont interprétés comme des bits et des octets ou comment ces octets sont transférés vers et depuis la mémoire et le CPU, et espérons que tout ce qui est géré par les programmes fournis par le système d'exploitation Dans les coulisses. Réfléchissons simplement à la façon dont vous ajoutez à la fin d'un fichier. 1) Découvrez où se trouve la fin du fichier, 2) écrivez quelque chose à cette position. Qu'est ce qui pourrait aller mal? En fait, beaucoup. Pensez à ce qui se passe d'autre sur l'ordinateur pendant que vous faites des choses intelligentes. Si quelque chose d'autre fait par quelqu'un d'autre (y compris le système d'exploitation lui-même) modifie le fichier sur lequel vous travaillez de quelque manière que ce soit, alors ce travail vraiment simple devient soudainement beaucoup plus compliqué. Le fichier est plus long, le fichier est plus court. Le fichier n'est plus là. Le disque est plein,

Paul Smith
la source