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() |
|
|
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 |