Partager via


Créer un traitement

Pour un système de fichiers, la plupart des travaux de sécurité intéressants se produisent pendant IRP_MJ_CREATE traitement. C’est cette étape qui doit analyser la demande entrante, déterminer si l’appelant dispose des droits appropriés pour effectuer l’opération et accorder ou refuser l’opération le cas échéant. Heureusement, pour les développeurs de systèmes de fichiers, la plupart du mécanisme de décision est implémenté dans le Moniteur de référence de sécurité. Ainsi, dans la plupart des cas, le système de fichiers n’a besoin que d’appeler les routines appropriées du Moniteur de référence de sécurité pour déterminer correctement l’accès. Le risque pour un système de fichiers se produit lorsqu’il ne parvient pas à appeler ces routines si nécessaire et accorde de manière inappropriée l’accès à un appelant.

Pour un système de fichiers standard, tel que le système de fichiers FAT, les vérifications effectuées dans le cadre de IRP_MJ_CREATE sont principalement des vérifications sémantiques. Par exemple, le système de fichiers FAT a de nombreuses vérifications pour s’assurer que IRP_MJ_CREATE traitement est autorisé en fonction de l’état du fichier ou du répertoire. Ces vérifications effectuées par le système de fichiers FAT incluent des vérifications des supports en lecture seule (par exemple, les tentatives d’exécution d’opérations destructrices de « création », telles que le remplacement ou le remplacement, sur un support en lecture seule ne sont pas autorisées), les vérifications d’accès de partage et les vérifications oplock. L’une des parties les plus difficiles de cette analyse consiste à réaliser qu’une opération à un niveau (le niveau du fichier, par exemple) peut en fait être refusée en raison de l’état d’une ressource de niveau différent (le niveau du volume, par exemple). Par exemple, un fichier peut ne pas être ouvert si un autre processus a verrouillé exclusivement le volume. Les cas courants à case activée incluent :

  • Le niveau de fichier ouvert est-il compatible avec l’état de niveau volume ? Le verrouillage au niveau du volume doit être respecté. Ainsi, si un processus contient un verrou de niveau volume exclusif, seuls les threads de ce processus peuvent ouvrir des fichiers. Les threads d’autres processus ne doivent pas être autorisés à ouvrir des fichiers.

  • Le niveau de fichier ouvert est-il compatible avec l’état du média ? Certaines opérations « create » modifient le fichier dans le cadre de l’opération « create ». Cela inclut le remplacement, le remplacement et même la mise à jour de l’heure du dernier accès sur le fichier. Ces opérations de « création » ne sont pas autorisées sur le support en lecture seule et l’heure du dernier accès n’est pas mise à jour.

  • Le niveau de volume ouvert est-il compatible avec l’état de niveau fichier ? Un volume exclusif ouvert n’est pas autorisé s’il existe des fichiers existants ouverts sur le volume. Il s’agit d’un problème courant pour les nouveaux développeurs, car ils tentent d’ouvrir le volume et constatent qu’il échoue. En cas d’échec, FSCTL_DISMOUNT_VOLUME peut être utilisé pour invalider les handles ouverts et forcer un démontage, ce qui permet un accès exclusif au volume nouvellement monté.

En outre, les attributs de fichier doivent être compatibles. Impossible d’ouvrir un fichier avec l’attribut en lecture seule pour l’accès en écriture. Notez que l’accès souhaité doit être vérifié après l’extension des droits génériques. Par exemple, cette case activée dans le système de fichiers FASTFAT se trouve dans la fonction FatCheckFileAccess (consultez le fichier source Acchksup.c à partir des exemples fastfat que contient le WDK).

L’exemple de code suivant est spécifique à la sémantique FAT. Un système de fichiers qui implémente également des dll DACL ferait une case activée de sécurité supplémentaire à l’aide des routines du Moniteur de référence de sécurité (SeAccessCheck, par exemple).)

    //
    //  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 );
        }

Une case activée plus subtile implémentée par FASTFAT consiste à s’assurer que l’accès demandé par l’appelant est un élément dont le système de fichiers FAT est conscient (dans la fonction FatCheckFileAccess dans Acchksup.c à partir de l’exemple fastfat que contient le WDK) :

L’exemple de code suivant illustre un concept important pour la sécurité du système de fichiers. Vérifiez que ce qui est passé à votre système de fichiers ne sort pas des limites de ce que vous attendez. L’approche conservatrice et appropriée du point de vue de la sécurité est que si vous ne comprenez pas une demande d’accès, vous devez rejeter cette demande.

    //
    // 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 );
    }

Heureusement pour les systèmes de fichiers, une fois la case activée de sécurité effectuée lors du traitement initial de la création, les vérifications de sécurité suivantes sont effectuées par le gestionnaire d’E/S. Ainsi, par exemple, le gestionnaire d’E/S garantit que les applications en mode utilisateur n’effectuent pas d’opération d’écriture sur un fichier qui a été ouvert uniquement pour l’accès en lecture. En fait, un système de fichiers ne doit pas tenter d’appliquer la sémantique en lecture seule à l’objet de fichier, même s’il a été ouvert uniquement pour l’accès en lecture, pendant la routine de distribution IRP_MJ_WRITE. Cela est dû à la façon dont le gestionnaire de mémoire associe un objet de fichier spécifique à un objet de section donné. L’écriture ultérieure de cette section sera envoyée en tant que IRP_MJ_WRITE opérations sur l’objet fichier, même si le fichier a été ouvert en lecture seule. En d’autres termes, l’application de l’accès est effectuée lorsqu’un handle de fichier est converti en l’objet de fichier correspondant aux points d’entrée du service système Nt par ObReferenceObjectByHandle.

Il existe deux emplacements supplémentaires dans un système de fichiers où les vérifications sémantiques de sécurité doivent être effectuées comme un traitement « créer » :

  • Pendant le traitement du renommage ou du lien dur.

  • Lors du traitement des opérations de contrôle du système de fichiers.

Le traitement du renommage et le traitement du contrôle du système de fichiers sont abordés dans les sections suivantes.

Notez qu’il ne s’agit pas d’une liste exhaustive de problèmes sémantiques liés au traitement « créer ». L’objectif de cette section est d’attirer l’attention sur ces problèmes pour les développeurs de systèmes de fichiers. Tous les problèmes sémantiques doivent être identifiés pour un système de fichiers spécifique, implémentés pour répondre à la sémantique spécifique et testés pour s’assurer que l’implémentation gère les différents cas.