Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Per un file system, la maggior parte delle attività di sicurezza interessanti si verifica durante l'elaborazione IRP_MJ_CREATE . Si tratta di questo passaggio che deve analizzare la richiesta in ingresso, determinare se il chiamante dispone dei diritti appropriati per eseguire l'operazione e concedere o negare l'operazione in base alle esigenze. Fortunatamente, per gli sviluppatori di file system, la maggior parte del meccanismo decisionale viene implementata all'interno del Security Reference Monitor. Pertanto, nella maggior parte dei casi, il file system deve semplicemente invocare le routine appropriate del Monitor di Riferimento della Sicurezza per determinare correttamente l'accesso. Il rischio per un file system si verifica quando non riesce a chiamare queste routine in base alle esigenze e concede in modo inappropriato l'accesso a un chiamante.
Per un file system standard, ad esempio il file system FAT, i controlli effettuati come parte di IRP_MJ_CREATE sono principalmente controlli semantici. Ad esempio, il file system FAT dispone di numerosi controlli per garantire che IRP_MJ_CREATE elaborazione sia consentita in base allo stato del file o della directory. Questi controlli eseguiti dal file system FAT includono controlli per i supporti di sola lettura (ad esempio, i tentativi di eseguire operazioni distruttive di "creazione", ad esempio sovrascrivere o sostituire, sui supporti di sola lettura non sono consentiti), i controlli di accesso alla condivisione e i controlli oplock. Una delle parti più difficili di questa analisi consiste nel rendersi conto che un'operazione a un certo livello (ad esempio, a livello di file) può essere vietata a causa dello stato di una risorsa a un altro livello (ad esempio, il livello del volume). Ad esempio, un file potrebbe non essere aperto se un altro processo ha bloccato esclusivamente il volume. I casi comuni da controllare includono:
Il livello del file è compatibile con lo stato del livello di volume? Il blocco a livello di volume deve essere rispettato. Pertanto, se un processo contiene un blocco esclusivo a livello di volume, solo i thread all'interno di tale processo possono aprire i file. I thread di altri processi non devono essere autorizzati ad aprire file.
Il livello del file aperto è compatibile con lo stato del supporto? Alcune operazioni di "creazione" modificano il file come parte dell'operazione di "creazione". Ciò include la sovrascrittura, la sostituzione e anche l'aggiornamento dell'ora dell'ultimo accesso nel file. Queste operazioni di "creazione" non sono consentite nei supporti di sola lettura e l'ora dell'ultimo accesso non viene aggiornata.
Il livello di volume è compatibile con lo stato a livello di file? Non è consentito un volume esclusivo aperto se nel volume sono aperti file esistenti. Si tratta di un problema comune per i nuovi sviluppatori perché tentano di aprire il volume e scoprire che non riescono. Quando questo fallisce, è possibile utilizzare FSCTL_DISMOUNT_VOLUME per invalidare gli handle aperti e forzare lo smontaggio, consentendo l'accesso esclusivo al volume appena montato.
Inoltre, gli attributi del file devono essere compatibili. Impossibile aprire un file con l'attributo di sola lettura per l'accesso in scrittura. Si noti che l'accesso desiderato deve essere controllato dopo l'espansione dei diritti generici. Ad esempio, questo controllo all'interno del file system FASTFAT si trova nella funzione FatCheckFileAccess (vedere il file di origine Acchksup.c dagli esempi fastfat contenuti in WDK).
L'esempio di codice seguente è specifico della semantica FAT. Un file system che implementa anche DACL esegue un controllo di sicurezza aggiuntivo usando le routine del Security Reference Monitor (ad esempio, SeAccessCheck).
//
// check for a read-only Dirent
//
if (FlagOn(DirentAttributes, FAT_DIRENT_ATTR_READ_ONLY)) {
//
// Check the desired access for a read-only Dirent
// Don't allow
// WRITE, FILE_APPEND_DATA, FILE_ADD_FILE,
// FILE_ADD_SUBDIRECTORY, and FILE_DELETE_CHILD
//
if (FlagOn(*DesiredAccess, ~(DELETE |
READ_CONTROL |
WRITE_OWNER |
WRITE_DAC |
SYNCHRONIZE |
ACCESS_SYSTEM_SECURITY |
FILE_READ_DATA |
FILE_READ_EA |
FILE_WRITE_EA |
FILE_READ_ATTRIBUTES |
FILE_WRITE_ATTRIBUTES |
FILE_EXECUTE |
FILE_LIST_DIRECTORY |
FILE_TRAVERSE))) {
DebugTrace(0, Dbg, "Cannot open readonly\n", 0);
try_return( Result = FALSE );
}
Un controllo più sottile implementato da FASTFAT consiste nel garantire che l'accesso richiesto dal chiamante sia qualcosa su cui il file system FAT è in grado di tenere presente (nella funzione FatCheckFileAccess in Acchksup.c dall'esempio fastfat contenuto dal wdk):
L'esempio di codice seguente illustra un concetto importante per la sicurezza del file system. Controllare che ciò che viene passato al file system non superi i limiti di quanto previsto. L'approccio conservativo e appropriato dal punto di vista della sicurezza è che, se non si comprende una richiesta di accesso, è necessario rifiutare tale richiesta.
//
// Check the desired access for the object.
// Reject what we do not understand.
// The model of file systems using ACLs is that
// they do not type the ACL to the object that the
// ACL is on.
// Permissions are not checked for consistency vs.
// the object type - dir/file.
//
if (FlagOn(*DesiredAccess, ~(DELETE |
READ_CONTROL |
WRITE_OWNER |
WRITE_DAC |
SYNCHRONIZE |
ACCESS_SYSTEM_SECURITY |
FILE_WRITE_DATA |
FILE_READ_EA |
FILE_WRITE_EA |
FILE_READ_ATTRIBUTES |
FILE_WRITE_ATTRIBUTES |
FILE_LIST_DIRECTORY |
FILE_TRAVERSE |
FILE_DELETE_CHILD |
FILE_APPEND_DATA))) {
DebugTrace(0, Dbg, "Cannot open object\n", 0);
try_return( Result = FALSE );
}
Fortunatamente per i file system, dopo aver eseguito il controllo di sicurezza durante l'elaborazione iniziale della creazione, i controlli di sicurezza successivi vengono eseguiti dal gestore di I/O. Ad esempio, il gestore di I/O garantisce che le applicazioni in modalità utente non eseguano un'operazione di scrittura su un file aperto solo per l'accesso in lettura. Infatti, un file system non deve tentare di applicare attributi di sola lettura all'oggetto file, anche se è stato aperto solo per l'accesso in lettura, durante la routine di distribuzione IRP_MJ_WRITE. Ciò è dovuto al modo in cui gestione memoria associa un oggetto file specifico a un determinato oggetto sezione. La scrittura successiva attraverso quella sezione verrà inviata come operazioni IRP_MJ_WRITE sull'oggetto file, anche se il file è stato aperto in sola lettura. In altre parole, l'applicazione delle restrizioni di accesso viene eseguita quando un handle di file viene convertito nell'oggetto file corrispondente ai punti di ingresso del servizio di sistema Nt tramite ObReferenceObjectByHandle.
Esistono due posizioni aggiuntive all'interno di un file system in cui i controlli di sicurezza semantica devono essere eseguiti in modo simile all'elaborazione "create":
Durante l'elaborazione di rinomina o collegamento fisso.
Durante l'elaborazione delle operazioni di controllo del file system.
L'elaborazione di rinomina e l'elaborazione del controllo del file system vengono discusse nelle sezioni successive.
Si noti che non si tratta di un elenco completo di problemi semantici correlati all'elaborazione di "creazione". Lo scopo di questa sezione è attirare l'attenzione su questi problemi per gli sviluppatori di file system. Tutti i problemi semantici devono essere identificati per un file system specifico, implementati per soddisfare la semantica specifica e testati per garantire che l'implementazione gestisca i vari casi.