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:

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()
  • Please OR/set the flag parameter with/to POOL_NX_ALLOCATION
  • Or by using the POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN methods above
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

POOL_TYPE