Partager via


Avertissement C30030

Appel d’une fonction d’allocation de mémoire et passage d’un paramètre qui indique la mémoire exécutable

Certaines API ont des paramètres qui configurent si la mémoire est exécutable ou non. Cette erreur indique que les paramètres utilisés entraînent l’allocation de l’exécutable NonPagedPool.

Remarques

Vous devez utiliser l’une des options disponibles pour demander de la mémoire non exécutable. Vous trouverez la liste de toutes les fonctions et indicateurs interdits couverts par cette erreur, ainsi que les remplacements recommandés en bas de cette page.

Nom de l’analyse Cose : BANNED_MEM_ALLOCATION_UNSAFE

Pour les défauts impliquant les types de paramètres MM_PAGE_PRIORITY et POOL_TYPE

Utilisez l’une des options suivantes :

  • Spécifiez la définition du préprocesseur POOL_NX_OPTIN_AUTO dans les paramètres des sources/du projet.
  • Spécifiez la définition de préprocesseur POOL_NX_OPTIN dans les paramètres de sources/projet et appelez ExInitializeDriverRuntime(DrvRtPoolNxOptIn) à partir de la fonction d’initialisation du pilote (DriverEntry ou DllInitialize).

Note Le choix d’utiliser POOL_NX_OPTIN_AUTO ou POOL_NX_OPTIN dépend en grande partie de la plateforme que vous ciblez et du nombre de fichiers binaires que vous créez. Ces deux options entraînent la modification de ces deux types pour vous (par le compilateur ou au moment de l’exécution) en leurs équivalents NX. Pour plus d’informations, consultez les liens de rubrique.

Note Vous pouvez voir un avertissement de faux positif si l’une des conditions suivantes est remplie :

  • La fonction d’initialisation du pilote appelle une autre fonction qui appelle ExInitializeDriverRuntime(DrvRtPoolNxOptIn)
  • Vous créez un DRIVER_LIBRARY et avez spécifié POOL_NX_OPTIN mais aucune fonction d’initialisation.
  • Remplacez le type d’allocation par un type non exécutable.

Exemple (POOL_NX_OPTIN_AUTO) :

Le paramètre suivant dans le fichier sources autorise l’avertissement si un paramètre exécutable est fourni dans un appel d’API :

C_DEFINES=$(C_DEFINES)

Le paramètre suivant dans le fichier sources évite l’avertissement :

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

Exemple (POOL_NX_OPTIN) :

Le code suivant dans le fichier sources génère un avertissement :

C_DEFINES=$(C_DEFINES)

Le code suivant dans le fichier sources évite l’avertissement :

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

Dans DriverEntry(), avant toute allocation de mémoire :

NTSTATUS
DriverEntry (
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status;

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

Exemple (Modifier le type d’allocation) :

Pour le type MM_PAGE_PRIORITY , vous pouvez résoudre ce problème en ajoutant l’indicateur MdlMappingNoExecute au type de priorité. Cela est pris en charge uniquement sur Windows 8 et versions ultérieures.

Le code suivant génère un avertissement :

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

Le code suivant évite l’avertissement :

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

Exemple (POOL_TYPE)

Pour le type POOL_TYPE , vous pouvez résoudre ce problème en remplaçant le type de requête par la version non exécutable du type. Cela est pris en charge uniquement sur Windows 8 et versions ultérieures.

Le code suivant génère un avertissement :

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

Le code suivant évite l’avertissement :

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

Autres cas spéciaux :

Une modification a été apportée à la routine ExInitializeNPagedLookasideList qui vous permet désormais de spécifier la mémoire du pool non exécutable non paginée. Par exemple, le code suivant génère cet avertissement :

ExInitializeNPagedLookasideList(pLookaside,
                NULL,
                NULL,
                0,
                size,
                tag,
                depth);

Le code suivant évite cet avertissement :

ExInitializeNPagedLookasideList(pLookaside,
                NULL,
                NULL,
                POOL_NX_ALLOCATION,
                size,
                tag,
                depth);

Pour les défauts impliquant des protections de page :

Certaines API vous permettent de spécifier des protections de page. ZwMapViewOfSection en fait partie. Dans ce cas, utilisez la version non exécutable du type de protection.

Changement:

  • PAGE_EXECUTE à l’une des alternatives ou PAGE_NOACCESS ci-dessous
  • PAGE_EXECUTE_READ à PAGE_READONLY
  • PAGE_EXECUTE_READWRITE à PAGE_READWRITE
  • PAGE_EXECUTE_WRITECOPY à PAGE_WRITECOPY

Le code suivant génère un avertissement :

Status = ZwMapViewOfSection(   handle,
                NtCurrentProcess(),
                Address,
                0,
                0,
                &SectionOffset,
                Size,
                ViewUnmap,
                MEM_LARGE_PAGES,
                PAGE_EXECUTE_READWRITE
                ); 

Le code suivant évite cet avertissement :

Status = ZwMapViewOfSection(   handle,
                NtCurrentProcess(),
                Address,
                0,
                0,
                &SectionOffset,
                Size,
                ViewUnmap,
                MEM_LARGE_PAGES,
                PAGE_READWRITE
                ); 

Pour les défauts impliquant des types de cache :

Certaines API allouent de la mémoire avec des autorisations exécutables dépendantes d’un type de cache. Deux API de ce type sont MmAllocateContiguousMemorySpecifyCache et MmAllocateContiguousMemorySpecifyCacheNode. Si un type de cache MmCached est utilisé (voir MEMORY_CACHING_TYPE), la mémoire exécutable est allouée. Pour résoudre ce problème, sélectionnez un autre type de mise en cache ou, si la mémoire mise en cache est nécessaire, utilisez l’API MmAllocateContiguousNodeMemory.

Changement:

  • MmCached sur MmNonCached ou MmWriteCombined si la mémoire mise en cache n’est pas nécessaire
  • L’API vers MmAllocateContiguousNodeMemory si la mémoire mise en cache est requise

Le code suivant génère un avertissement :

MmAllocateContiguousMemorySpecifyCache(       numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmCached,
                                              ); 

Le code suivant évite cet avertissement si la mémoire mise en cache n’est pas nécessaire :

MmAllocateContiguousMemorySpecifyCache(       numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmNonCached,
                                              ); 

Le code suivant génère un avertissement :

MmAllocateContiguousMemorySpecifyCacheNode(   numberOfBytes,
                                              lowestAddress,
                                              highestAddress,
                                              NULL,
                                              MmCached,
                                              MM_ANY_NODE_OK
                                              ); 

Le code suivant évite cet avertissement si la mémoire mise en cache est nécessaire :

MmAllocateContiguousNodeMemory(       numberOfBytes,
                                      lowestAddress,
                                      highestAddress,
                                      NULL,
                                      PAGE_READWRITE,
                                      MM_ANY_NODE_OK
                                      ); 

Le code suivant utilise l’autre API lorsque la mémoire mise en cache n’est pas nécessaire :

MmAllocateContiguousNodeMemory(       numberOfBytes,
                                      lowestAddress,
                                      highestAddress,
                                      NULL,
                                      PAGE_READWRITE | PAGE_NOCACHE,
                                      MM_ANY_NODE_OK
                                      ); 

Fonctions interdites

API interdite Remplacement(s) Justification / Remarques
ExInitializeNPagedLookasideList()
  • Veuillez OU/définir le paramètre d’indicateur avec/à POOL_NX_ALLOCATION
  • Ou en utilisant les POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN méthodes ci-dessus
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() Pour plus d’informations, voir ci-dessus

Indicateurs interdits

Indicateur interdit Remplacement(s) Justification/Remarques
MM_PAGE_PRIORITY

Pour plus d’informations, voir ci-dessus
POOL_NX_OPTIN_AUTO Cela prend en charge la création de plusieurs fichiers binaires pour différentes versions de Windows
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) Cela prend en charge un fichier binaire unique s’exécutant sur différentes versions de Windows
PagePriority / MdlMappingNoExecute Cela fonctionnera sur Windows 8 et versions ultérieures
PAGE_EXECUTE PAGE_NOACCESS Pour plus d’informations, voir ci-dessus
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE