Condividi tramite


Utilizzare SafeHandle per incapsulare le risorse native

Aggiornamento: novembre 2007

TypeName

UseSafeHandleToEncapsulateNativeResources

CheckId

CA2006

Categoria

Microsoft.Reliability

Breaking Change

Non sostanziale

Causa

Il codice gestito utilizza IntPtr per accedere alle risorse native.

Descrizione della regola

L'utilizzo di IntPtr nel codice gestito potrebbe indicare un potenziale problema di protezione e affidabilità. Tutte le occorrenze di IntPtr devono essere esaminate per stabilire se al loro posto era necessario utilizzare SafeHandle o una tecnologia simile. Si verificheranno problemi nel caso in cui IntPtr rappresenti risorse native quali memoria, handle di file, socket e così via a cui si considera che appartenga il codice gestito. In pratica, si prevede che il codice gestito rilasci la risorsa e la mancata riuscita di tale operazione determinerà la perdita della risorsa.

In scenari di questo tipo si verificheranno anche problemi di protezione o affidabilità nel caso in cui sia consentito l'accesso multithread a IntPtr e un sistema per il rilascio della risorsa sia rappresentato da IntPtr. Tali problemi riguardano il riciclo del valore IntPtr sul rilascio della risorsa mentre su un altro thread la risorsa viene utilizzata contemporaneamente, determinando race condition nel caso in cui un thread sia in grado di leggere o scrivere dati associati alla risorsa sbagliata. Se nel tipo, ad esempio, è memorizzato un gestore OS come IntPtr e viene consentito agli utenti di chiamare Close e qualsiasi altro metodo che utilizza quel gestore simultaneamente e senza alcun tipo di sincronizzazione, il codice presenterà un problema di riciclo del gestore.

Tale problema determina il danneggiamento dei dati e, spesso, una vulnerabilità della protezione. SafeHandle e la relativa classe di pari livello CriticalHandle forniscono un meccanismo per incapsulare un gestore nativo in una risorsa, in modo da evitare tali problemi di threading. È inoltre possibile utilizzare SafeHandle e la relativa classe CriticalHandle di pari livello per altri problemi di threading, ad esempio per controllare con attenzione la durata degli oggetti gestiti che contengono una copia del gestore nativo nelle chiamate ai metodi nativi. In questa situazione è spesso possibile rimuovere le chiamate a GC.KeepAlive. Alcuni overhead di prestazione impliciti nell'utilizzo di SafeHandle e, a livello inferiore, di CriticalHandle, possono spesso essere ridotti attraverso un'attenta progettazione.

Correzione delle violazioni

Convertire l'utilizzo di IntPtr in SafeHandle per gestire in modo sicuro l'accesso alle risorse native.

Esclusione di avvisi

Non escludere tale avviso.