2009-06-29 6 views
12

Comment Windows protège-t-il contre un thread en mode utilisateur de la transition arbitraire de l'UC en mode noyau?Comment Windows protège-t-il la transition en mode noyau?

Je comprends ces choses sont vraies:

  1. threads en mode utilisateur ne fait la transition au mode noyau lorsqu'un appel système est fait par NTDLL.
  2. La transition vers le mode noyau s'effectue via des instructions spécifiques au processeur.

Alors, quelle est la particularité de ces appels système via NTDLL? Pourquoi le thread en mode utilisateur ne peut-il pas fake-it et exécuter les instructions spécifiques au processeur pour passer en mode kernel? Je sais qu'il me manque un élément clé de l'architecture Windows ici ... qu'est-ce que c'est?

+0

Le thread en mode utilisateur peut truquer, mais en quoi cela serait-il différent de simplement utiliser ntdll.dll? Ajoutez aux questions plus d'informations sur pourquoi cela vous concerne. –

+2

Je pense que l'OP est inquiet à propos de la transition vers l'anneau 0, puis l'exécution de code non-O/S arbitraire alors que l'anneau 0. – ChrisW

+1

Windows effectue une validation sur ses paramètres exposés (à usermode). Vous ne pouvez pas * transmettre des données non valides sans le savoir. Oui, il y a des cas d'angle négligés. Juste, recherchez les vulnérabilités d'escalade de privilèges locaux. Il y a une tonne d'entre eux – unixman83

Répondre

17

Vous pensez probablement que le thread s'exécutant en mode utilisateur appelle Ring 0, mais ce n'est pas ce qui se passe réellement. Le thread du mode utilisateur provoque une exception qui est interceptée par le code Ring 0. Le thread de mode utilisateur est arrêté et la CPU passe à un thread noyau/anneau 0, qui peut ensuite inspecter le contexte (par exemple, la pile d'appels et les registres) du thread de mode utilisateur pour déterminer ce qu'il faut faire. Avant syscall, c'était vraiment une exception plutôt qu'une exception spéciale spécifiquement pour invoquer le code ring 0.

Si vous suivez les conseils des autres réponses et que vous lisez the Intel manuals, vous verrez que syscall/sysenter ne prend aucun paramètre - l'OS décide ce qui se passe. Vous ne pouvez pas appeler du code arbitraire. WinNT utilise des numéros de fonction qui correspondent à la fonction du mode noyau que le code du mode utilisateur exécutera (par exemple, NtOpenFile est fnc 75h sur ma machine Windows XP (les numéros changent tout le temps, c'est l'une des tâches de NTDll de mapper un appelez un numéro fnc, placez-le dans EAX, indiquez le paramètre EDX aux paramètres entrants, puis appelez sysenter)

9

Les processeurs Intel renforcent la sécurité en utilisant ce que l'on appelle les «anneaux de protection».

Il y en a 4, numérotés de 0 à 3. Le code s'exécutant dans l'anneau 0 a les privilèges les plus élevés; il peut (pratiquement) faire ce qu'il veut avec votre ordinateur. Le code dans l'anneau 3, d'autre part, est toujours sur une laisse serrée; il n'a que des pouvoirs limités pour influencer les choses. Et les anneaux 1 et 2 ne sont actuellement utilisés à aucune fin.

Un thread s'exécutant dans un anneau privilégié supérieur (tel que l'anneau 0) peut passer à un anneau de privilège inférieur (tel que l'anneau 1, 2 ou 3) à volonté. Cependant, la transition à l'inverse est strictement réglementée. C'est ainsi que la sécurité des ressources hautement privilégiées (telles que la mémoire) etc. est maintenue. Naturellement, votre code de mode utilisateur (applications et tout) s'exécute dans l'anneau 3 pendant que le code du système s'exécute dans l'anneau 0. Cela garantit que les threads en mode utilisateur ne peuvent pas déranger les structures de données du système d'exploitation et autres ressources critiques.

Pour plus de détails sur la façon dont tout cela est réellement implémenté, vous pouvez lire l'article this. En outre, vous pouvez également passer par les manuels Intel, en particulier Vol 1 et Vol 3A, que vous pouvez télécharger here.

C'est l'histoire des processeurs Intel. Je suis sûr que d'autres architectures ont quelque chose de similaire.

+2

La plupart des autres processeurs se contentent de deux niveaux de privilège essentiellement équivalents aux anneaux x86 0 et 3. Les anneaux 1 et 2 semblaient probablement être une bonne idée à ce moment, mais ils n'ont ajouté aucune valeur à la complexité qu'ils coûtent. – RBerteig

+1

IIRC Windows utilise seulement 2 anneaux car c'est tout ce que supportent les architectures RISC. Comme ils voulaient soutenir RISC avec la même architecture de base, seuls les anneaux x86 extrêmes sont utilisés. – noctonura

7

Je pense (je peux me tromper) que le mécanisme qu'il utilise pour la transition est simple:

  • code en mode utilisateur exécute un logiciel d'interruption
  • Cette (interruption) provoque une branche à un endroit spécifié dans la table descripteurs d'interruption (IDT)

Ce qui empêche le code en mode utilisateur de l'usurper est le suivant: vous devez avoir le privilège d'écrire dans l'IDT; donc seul le noyau est capable de spécifier ce qui se passe quand une interruption est exécutée.

+0

Big chris répondant jeune chris. –

+0

C'est comme ça * utilisé * pour fonctionner, mais la réponse de Tony Lee est beaucoup plus proche de ce que Windows fait aujourd'hui. –

+1

J'ai sauté la partie sur l'IDT/comment le CPU sait où commencer à s'exécuter donc c'est intéressant d'inclure aussi. –

4

Le code exécuté en mode utilisateur (sonnerie 3) ne peut pas changer arbitrairement en mode noyau (sonnerie 0). ne peuvent le faire qu'en utilisant des routes spéciales - les portails de saut, les interruptions, et les vecteurs de sysenter.Ces routes sont hautement protégées et l'entrée est nettoyée pour que les mauvaises données ne causent pas (ne devraient pas) causer de mauvais comportement. est mis en place par le noyau, généralement au démarrage, il ne peut être configuré qu'en mode noyau donc User-Mo de code ne peut pas le modifier.

3

Il est probablement juste de dire qu'il le fait d'une manière (relativement) similaire à ce que fait Linux. Dans les deux cas, il sera spécifique à l'unité centrale, mais sur x86, il s'agira probablement soit d'une interruption logicielle avec l'instruction INT, soit d'une instruction SYSENTER. L'avantage de regarder comment Linux le fait est que vous pouvez le faire sans une licence source Windows.

Le userspace source part is here here à LXR et kernel space bit - regardez entry_32.S et entry_64.S

Sous Linux sur x86, il y a trois mécanismes différents, int 0x80, syscall et sysenter.

Une bibliothèque construite à l'exécution par le noyau appelé vdso est appelée par la bibliothèque C pour implémenter la fonction syscall, qui utilise un mécanisme différent en fonction de la CPU et de l'appel système. Le noyau a alors des gestionnaires pour ces mécanismes (s'ils existent sur la variante CPU spécifique).

Questions connexes