L'utilisation de IntPtr dans du code managé peut être le signe d'un problème potentiel de sécurité et de fiabilité. Toute ...

L'utilisation de IntPtr dans du code managé peut être le signe d'un problème potentiel de sécurité et de fiabilité. Toute utilisation de IntPtr doit être passée en revue pour déterminer s'il est nécessaire de recourir à un SafeHandle (ou une technologie similaire) à la place. Des problèmes surviendront si le IntPtr désigne une ressource native (mémoire, handle de fichier, socket, etc.) considérée comme élément appartenant au code managé, ce qui signifie que le code managé doit d'une manière ou d'une autre libérer la ressource et risque de provoquer une fuite de cette dernière s'il ne le fait pas. Des problèmes de sécurité ou de fiabilité se présenteront aussi dans des scénarios de ce type si l'accès multithread est accordé au IntPtr, tout comme la possibilité de libérer la ressource représentée par le IntPtr. Ces problèmes impliquent de recycler la valeur IntPtr lors de la libération de la ressource pendant l'utilisation simultanée de cette dernière sur un autre thread, ce qui entraîne des conditions de concurrence critique dans lesquelles un thread peut lire ou écrire des données associées à la mauvaise ressource. Par exemple, si votre type stocke un handle de système d'exploitation comme IntPtr et autorise les utilisateurs à appeler à la fois la méthode Close et toute autre méthode utilisant ce handle en même temps (avec un degré de synchronisation), votre code sera confronté à un problème de recyclage du handle susceptible d'endommager les données et, souvent, de rendre la sécurité plus vulnérable. SafeHandle (et sa classe soeur CriticalHandle) propose un mécanisme permettant d'encapsuler un handle natif dans une ressource pour éviter ces problèmes de thread (ainsi que d'autres problèmes, notamment la nécessité de contrôler avec soin la durée de vie des objets managés contenant une copie du handle natif par rapport aux appels aux méthodes natives, ce qui signifie que vous pouvez souvent supprimer des appels à GC.KeepAlive). L'utilisation de SafeHandle signifie implicitement une charge et une consommation système plus lourdes (et, à moindre degré, de CriticalHandle) qu'il est possible de minimiser avec une conception rigoureuse.