Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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 :
Une application qui transmet un 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.
Une application qui transmet une valeur qui n’est pas un descripteur approprié pour l’objet de périphérique (un descripteur que ce pilote n’a pas créé).
Pour protéger contre ces problèmes, un pilote de noyau doit être particulièrement prudent afin de s’assurer que les handles qui lui sont transmis 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 une prudence extrême.
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 la vérification des paramètres 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 vérifier pour des erreurs.
Les erreurs doivent être correctement interceptées en utilisant __try et __except si nécessaire. Un grand nombre des routines de la bibliothèque d'exécution Cc (cache manager), Mm (gestionnaire de mémoire) et FsRtl (système de fichiers) lèvent 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.