Warning C30030
Calling a memory allocating function and passing a parameter that indicates executable memory
Some APIs have parameters that configure whether memory is executable or not. This error indicates that parameters are used that result in executable NonPagedPool being allocated.
Remarks
You should use one of the available options to request non-executable memory. A list of all banned functions and flags covered by this error and the recommended replacements can be found at the bottom of this page.
Cose analysis name: BANNED_MEM_ALLOCATION_UNSAFE
For defects involving the parameter types MM_PAGE_PRIORITY and POOL_TYPE
Use one of the following options:
- Specify the preprocessor definition POOL_NX_OPTIN_AUTO in the sources/project settings.
- Specify the pre-processor definition POOL_NX_OPTIN in the sources/project settings and call ExInitializeDriverRuntime(DrvRtPoolNxOptIn) from the driver initialization function (DriverEntry or DllInitialize).
Note The choice of whether to use POOL_NX_OPTIN_AUTO or POOL_NX_OPTIN largely depends on which platform you are targeting and how many binaries you are making. Both of these options result in these two types being changed for you (either by the compiler or at run time) to their NX equivalents. See the topic links for more information.
Note You may see a false positive warning if one of the following conditions is true:
- The driver initialization function calls another function that calls ExInitializeDriverRuntime(DrvRtPoolNxOptIn)
- You are creating a DRIVER_LIBRARY and have specified POOL_NX_OPTIN but have no initialization function.
- Change the allocation type to a non-executable type.
Example (POOL_NX_OPTIN_AUTO):
The following setting in the sources file would allow the warning should an executable parameter be supplied in an API call:
C_DEFINES=$(C_DEFINES)
The following setting in the sources file avoids the warning:
C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1
Example (POOL_NX_OPTIN):
The following code in the sources file generates a warning:
C_DEFINES=$(C_DEFINES)
The following code in the sources file avoids the warning:
C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1
In DriverEntry(), before any memory allocation takes place:
NTSTATUS
DriverEntry (
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…
Example (Change the allocation type):
For the MM_PAGE_PRIORITY type you can fix this by adding the MdlMappingNoExecute flag to the priority type. This is only supported on Windows 8 and later.
The following code generates a warning:
pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);
The following code avoids the warning:
pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);
Example (POOL_TYPE)
For the POOL_TYPE type you can fix this by changing the request type to the non-executable version of the type. This is only supported on Windows 8 and later.
The following code generates a warning:
ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');
The following code avoids the warning:
ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');
Other special cases:
There has been a change in the ExInitializeNPagedLookasideList routine that now enables you to specify non-executable nonpaged pool memory. For example, the following code generates this warning:
ExInitializeNPagedLookasideList(pLookaside,
NULL,
NULL,
0,
size,
tag,
depth);
The following code avoids this warning:
ExInitializeNPagedLookasideList(pLookaside,
NULL,
NULL,
POOL_NX_ALLOCATION,
size,
tag,
depth);
For defects involving page protections:
Some APIs allow you to specify page protections, ZwMapViewOfSection is one of these. In these cases, use the non-executable version of the protection type.
Change:
- PAGE_EXECUTE to any of the below alternatives or PAGE_NOACCESS
- PAGE_EXECUTE_READ to PAGE_READONLY
- PAGE_EXECUTE_READWRITE to PAGE_READWRITE
- PAGE_EXECUTE_WRITECOPY to PAGE_WRITECOPY
The following code generates a warning:
Status = ZwMapViewOfSection( handle,
NtCurrentProcess(),
Address,
0,
0,
&SectionOffset,
Size,
ViewUnmap,
MEM_LARGE_PAGES,
PAGE_EXECUTE_READWRITE
);
The following code avoids this warning:
Status = ZwMapViewOfSection( handle,
NtCurrentProcess(),
Address,
0,
0,
&SectionOffset,
Size,
ViewUnmap,
MEM_LARGE_PAGES,
PAGE_READWRITE
);
For defects involving cache types:
Some APIs allocate memory with executable permissions dependent on a cache type. Two such APIs are MmAllocateContiguousMemorySpecifyCache and MmAllocateContiguousMemorySpecifyCacheNode. Should a cache type of MmCached be used (see MEMORY_CACHING_TYPE), then executable memory will be allocated. To fix this, either select another caching type, or if cached memory is required then use the API MmAllocateContiguousNodeMemory.
Change:
- MmCached to MmNonCached or MmWriteCombined if cached memory is not required
- The API to MmAllocateContiguousNodeMemory if cached memory is required
The following code generates a warning:
MmAllocateContiguousMemorySpecifyCache( numberOfBytes,
lowestAddress,
highestAddress,
NULL,
MmCached,
);
The following code avoids this warning if cached memory is not required:
MmAllocateContiguousMemorySpecifyCache( numberOfBytes,
lowestAddress,
highestAddress,
NULL,
MmNonCached,
);
The following code generates a warning:
MmAllocateContiguousMemorySpecifyCacheNode( numberOfBytes,
lowestAddress,
highestAddress,
NULL,
MmCached,
MM_ANY_NODE_OK
);
The following code avoids this warning if cached memory is required:
MmAllocateContiguousNodeMemory( numberOfBytes,
lowestAddress,
highestAddress,
NULL,
PAGE_READWRITE,
MM_ANY_NODE_OK
);
The following code use the alternative API when cached memory is not required:
MmAllocateContiguousNodeMemory( numberOfBytes,
lowestAddress,
highestAddress,
NULL,
PAGE_READWRITE | PAGE_NOCACHE,
MM_ANY_NODE_OK
);
Banned Functions
Banned API | Replacement(s) | Rationale / Notes |
---|---|---|
ExInitializeNPagedLookasideList() |
|
|
MmAllocateContiguousMemorySpecifyCache() |
MmAllocateContiguousNodeMemory() |
See above for more information |
Banned Flags
Banned Flag | Replacement(s) | Rationale/Notes |
---|---|---|
MM_PAGE_PRIORITY See above for more information |
POOL_NX_OPTIN_AUTO |
This supports creating multiple binaries for different versions of Windows |
POOL_NX_OPTIN (+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn) ) |
This supports a single binary running on different versions of Windows | |
PagePriority / MdlMappingNoExecute |
This will work on Windows 8 and later | |
PAGE_EXECUTE |
PAGE_NOACCESS |
See above for more information |
PAGE_EXECUTE_READ |
PAGE_READONLY |
|
PAGE_EXECUTE_READWRITE |
PAGE_READWRITE |
|
PAGE_EXECUTE_WRITECOPY |
PAGE_WRITECOPY |