Que sont les anneaux 0 et 3 dans le contexte des systèmes d'exploitation?

j'ai appris les bases sur le développement des pilotes dans Windows je n'arrête pas de trouver les Termes Ring 0 et Ring 3 . Que faire de ces reportez-vous à? S'agit-il de la même chose que mode noyau et mode utilisateur ?

20

3 réponses

Linux x86 anneau d'utilisation vue d'ensemble

comprendre comment les anneaux sont utilisés dans Linux vous donnera une bonne idée de ce pour quoi ils sont conçus.

en mode protégé x86, le CPU est toujours dans l'un des 4 anneaux. Le noyau Linux n'utilise que 0 et 3:

  • 0 pour kernel
  • 3 pour les utilisateurs

C'est le plus dur et rapide définition de kernel vs userland.

pourquoi Linux n'utilise pas les anneaux 1 et 2: les anneaux de privilège CPU: pourquoi les anneaux 1 et 2 ne sont pas utilisés?

comment détermine-t-on l'anneau actuel?

l'anneau courant est sélectionné par une combinaison de:

  • global descriptor table: une table en mémoire de GDT d'entrées, chaque entrée dispose d'un champ Privl qui Code l'anneau.

    l'instruction LGDT définit l'adresse de la table de descripteurs actuelle.

    Voir aussi: http://wiki.osdev.org/Global_Descriptor_Table

  • le segment enregistre CS, DS, etc., qui pointent vers l'index d'une entrée dans le GDT.

    par exemple, CS = 0 signifie que la première entrée du GDT est actuellement active. pour le code d'exécution.

que peut faire chaque bague?

la puce CPU est physiquement construite de sorte que:

  • ring 0 ne pouvez rien faire

  • ring 3 ne peut pas exécuter plusieurs instructions et d'écrire à plusieurs registres, notamment:

    • ne peut pas changer sa propre bague! Sinon, il pourrait se mettre à l'anneau 0 et les anneaux seraient inutiles.

      en d'autres termes, ne peut pas modifier l'actuel segment descripteur , qui détermine l'anneau courant.

    • ne peut pas modifier les tableaux de page: Comment fonctionne x86 paging?

      en d'autres termes, ne peut pas modifier le registre CR3, et paging lui-même empêche la modification de la page table.

      ceci empêche un processus de voir la mémoire d'autres processus pour des raisons de sécurité / facilité de programmation.

    • ne peut enregistrer les manipulateurs d'interruption. Ceux-ci sont configurés en écrivant à des emplacements de mémoire, qui est également empêchée par la pagination.

      Gestionnaires d'exécuter en ring 0, et de casser le modèle de sécurité.

      en d'autres termes, ne peut pas utiliser le LGDT et LIDT instruction.

    • ne peut pas faire des instructions IO comme in et out , et donc avoir des accès matériels arbitraires.

      autrement, par exemple, les permissions de fichiers seraient inutiles si n'importe quel programme pouvait lire directement à partir du disque.

      plus précisément grâce à Michael Petch : il est en fait possible pour L'OS de permettre IO instructions sur l'anneau 3, Ce est en fait contrôlée par le segment D'État de tâche .

      ce qui n'est pas possible, c'est que l'anneau 3 se donne la permission de le faire s'il ne l'avait pas en premier lieu.

      Linux le refuse toujours. Voir aussi: pourquoi Linux n'utilise-t-il pas le commutateur de contexte matériel via le TSS?

Comment faire combien de programmes et d'exploitation la transition des systèmes entre les anneaux?

  • lorsque le CPU est activé, il commence à exécuter le programme initial dans l'anneau 0 (bien sorte de, mais c'est une bonne approximation). Vous pouvez penser que ce programme initial est le noyau (mais c'est normalement un bootloader qui appelle alors le noyau toujours dans le ring 0).

  • quand un processus userland veut que le noyau fasse quelque chose pour lui comme écrire à un fichier, il utilise une instruction qui génère une interruption comme int 0x80 pour signaler le noyau.

    lorsque cela se produit, le CPU appelle et interrompt le gestionnaire de rappel que le noyau a enregistré au démarrage.

    ce gestionnaire tourne dans le ring 0, qui décide si le noyau va permettre cette action, faire l'action, et redémarrer le programme userland dans le ring 3.

  • lorsque l'appel système exec est utilisé( ou lorsque le noyau va démarrer /init ), le noyau prépare les registres et la mémoire du nouveau processus userland, puis il saute au point d'entrée et commute le CPU à l'anneau 3

  • si le programme essaie de faire quelque chose de mal, comme écrire à un registre interdit ou à une adresse mémoire (à cause de la pagination), le CPU appelle aussi un gestionnaire de rappel du noyau dans le ring 0.

    mais puisque l'userland était méchant, le noyau pourrait tuer le processus cette fois, ou lui donner un avertissement avec un signal.

  • lorsque le noyau démarre, il configure une horloge matérielle avec une fréquence fixe, qui génère des interruptions périodiques.

    cette horloge matérielle génère des interruptions qui s'exécutent ring 0, et lui permettent de programmer quels processus userland pour se réveiller.

    par ici, horaire peut se produire même si les processus ne font aucun appel système.

Quel est le but d'avoir plusieurs anneaux?

il y a deux avantages majeurs à séparer kernel et userland:

  • il est plus facile de faire des programmes car vous êtes plus certain que l'un ne va pas interférer avec l'autre. Par exemple, un processus userland n'a pas à s'inquiéter de la réécriture de la mémoire d'un autre programme en raison de la pagination, ni sur le fait de mettre le matériel dans un état invalide pour un autre processus.
  • c'est plus sûr. Par exemple: les permissions de fichiers et la séparation de la mémoire pourrait empêcher une application de piratage de lire vos données bancaires. Cela suppose, bien sûr, que vous ayez confiance dans le noyau.

Comment jouer un peu avec elle?

j'ai créé une configuration en métal nu qui devrait être un bon moyen de manipuler les anneaux directement: https://github.com/cirosantilli/x86-bare-metal-examples

Je n'ai pas eu la patience de faire un exemple userland malheureusement, mais je suis allé jusqu'à la configuration de paging, donc userland devrait être faisable. J'aimerais voir une pull request.

alternativement, les modules du noyau Linux tournent dans le ring 0, de sorte que vous pouvez les utiliser pour essayer des opérations privilégiées, par exemple lire les registres de contrôle: comment accéder aux registres de contrôle cr0,cr2,cr3 à partir d'un programme? Erreur de segmentation

voici un pratique qemu + Buildroot setup pour l'essayer sans tuer votre hôte.

l'inconvénient des modules du noyau est que d'autres kthreads sont en cours d'exécution et pourraient interférer avec vos expériences. Mais en théorie, vous pouvez prendre en charge tous les gestionnaires d'interruption avec votre module du noyau et propre le système, ce serait une projet intéressant en fait.

Négatif anneaux

bien que les anneaux négatifs ne soient pas référencés dans le manuel Intel, il existe en fait des modes CPU qui ont d'autres possibilités que l'anneau 0 lui-même, et sont donc un bon ajustement pour le nom" anneau négatif".

un exemple est le mode hyperviseur utilisé dans la virtualisation.

pour plus de détails voir: https://security.stackexchange.com/questions/129098/what-is-protection-ring-1

BRAS

dans ARM, les anneaux sont appelés niveaux D'Exception à la place, mais les idées principales restent les mêmes.

Il existe 4 exception niveaux en ARMv8, couramment utilisé comme:

  • EL0: userland

  • EL1: kernel

  • EL2: hypervisors , par exemple Xen .

    un hyperviseur est à un OS, ce qu'un OS est à un userland.

    par exemple, Xen vous permet d'exécuter plusieurs os comme Linux ou Windows sur le même système en même temps, et il isole les os les uns des autres pour la sécurité et la facilité de débogage, tout comme Linux le fait pour les programmes userland.

    les hyperviseurs sont un élément clé de l'infrastructure cloud d'aujourd'hui: ils permettent à plusieurs serveurs de fonctionner sur un seul matériel, en maintenant l'utilisation du matériel toujours proche de 100% et en économisant beaucoup d'argent.

    AWS par exemple utilisé Xen, jusqu'en 2017, lors de la de son déplacement à KVM fait la une des journaux .

  • EL3: encore un autre niveau. TODO exemple.

Le ARMv8 Architecture Reference Model DDI 0487C.a - chapitre D1-le modèle de programmeur au niveau du système AArch64-la Figure D1-1 illustre cela magnifiquement:

enter image description here

notez comment ARM, peut-être en raison de l'avantage du recul, a une meilleure convention de nommage pour les niveaux de privilèges que x86, sans la nécessité de niveaux négatifs: 0 étant le plus bas et 3 le plus élevé. Des niveaux plus élevés ont tendance à être créé le plus souvent inférieurs.

31
Les processeurs Intel

(x86 et autres) autorisent des applications à pouvoirs limités. Pour restreindre (protéger) les ressources critiques comme IO, mémoire, ports, etc, CPU en liaison avec le système D'exploitation (Windows dans ce cas) fournit des niveaux de privilèges (0 étant le plus de privilèges à 3 étant le moins) qui correspondent respectivement au mode noyau et au mode utilisateur.

ainsi, le système d'exploitation exécute le code du noyau dans l'anneau 0 - Niveau de privilège le plus élevé (de 0) fourni par le CPU - et le code utilisateur dans l'anneau 3.

Pour en savoir plus, lisez . http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection /

11
répondu Ravi Tiwari 2015-10-20 18:56:16

Eh bien, c'est une question assez large. Cependant, vous pouvez utiliser google ou tout simplement lire les articles sur Wikipedia à propos de ces choses pour obtenir un premier aperçu.

2
répondu pzaenger 2017-05-20 15:27:28