Share via


Gérer la gestion

Une source importante de problèmes de sécurité au sein des pilotes est l’utilisation de handles passés entre les composants en mode utilisateur et en mode noyau. Il existe un certain nombre de problèmes connus liés à la gestion de l’utilisation dans l’environnement du noyau, notamment les suivants :

  • Application qui transmet le type de handle incorrect à un pilote de noyau. Le pilote du noyau peut se bloquer en essayant d’utiliser un objet d’événement où un objet de fichier est nécessaire.

  • Application qui transmet un handle à un objet pour lequel il n’a pas l’accès nécessaire. Le pilote de noyau peut effectuer une opération qui fonctionne, car l’appel provient du mode noyau, même si l’utilisateur n’a pas les autorisations appropriées pour le faire.

  • Application qui transmet une valeur qui n’est pas un handle valide dans son espace d’adressage, mais est marquée comme un handle système pour effectuer une opération malveillante sur le système.

  • Application qui transmet une valeur qui n’est pas un handle approprié pour l’objet d’appareil (handle que ce pilote n’a pas créé).

Pour vous protéger contre ces problèmes, un pilote de noyau doit être particulièrement prudent pour s’assurer que les handles passés à celui-ci sont valides. La stratégie la plus sûre consiste à créer tous les handles nécessaires dans le contexte du pilote. Ces handles, créés par les pilotes de noyau, doivent spécifier l’option OBJ_KERNEL_HANDLE, qui crée un handle valide dans le contexte de processus arbitraire et un qui est accessible uniquement à partir d’un appelant en mode noyau.

Pour les pilotes qui utilisent des handles créés par un programme d’application, l’utilisation de ces handles doit être effectuée avec des soins extrêmes :

  • La meilleure pratique consiste à convertir le handle en pointeur d’objet en appelant ObReferenceObjectByHandle, en spécifiant le accessMode correct (généralement à partir d’Irp-RequestorMode>), desiredAccess et les paramètres ObjectType, tels qu’IoFileObjectType ou ExEventObjectType.

  • Si un handle doit être utilisé directement dans un appel, il est préférable d’utiliser les variantes Nt des fonctions plutôt que les variantes Zw des fonctions. Cela applique le paramètre case activée et gère la validation par le système d’exploitation, car le mode précédent sera UserMode et, par conséquent, non approuvé. Notez que les paramètres passés aux fonctions Nt qui sont des pointeurs peuvent échouer à la validation si le mode précédent est UserMode. Les routines Nt et Zw retournent un paramètre IoStatusBlock avec des informations d’erreur que vous devez case activée pour les erreurs.

  • Les erreurs doivent être correctement interceptées en utilisant __try et __except si nécessaire. Un grand nombre des routines de bibliothèque de runtime du système de fichiers (Cc), de gestionnaire de mémoire (Mm) et de système de fichiers déclenchent une exception lorsqu’une erreur se produit.

Aucun pilote ne doit jamais s’appuyer sur des handles ou des paramètres transmis à partir d’une application en mode utilisateur sans prendre de précautions appropriées.

Notez que si la variante Nt est utilisée pour ouvrir un fichier, la variante Nt doit également être utilisée pour fermer le fichier.