警告 C30030

メモリ割り当て関数を呼び出し、実行可能メモリを示すパラメーターを渡す

一部の API には、メモリが実行可能かどうかを構成するパラメーターがあります。 このエラーは、実行可能な NonPagedPool が割り当てられるパラメーターが使用されていることを示します。

解説

実行不可能なメモリを要求するには、使用可能なオプションのいずれかを使用する必要があります。 このエラーの対象となるすべての禁止されている関数とフラグの一覧と推奨される代替関数は、このページの最後にあります。

コード分析名: BANNED_MEM_ALLOCATION_UNSAFE

パラメーター型 MM_PAGE_PRIORITY および POOL_TYPE に関連する欠陥の場合

次のいずれかのオプションを使用します。

  • ソース/プロジェクト設定でプリプロセッサ定義 POOL_NX_OPTIN_AUTO を指定します。
  • ソース/プロジェクト設定でプリプロセッサ定義 POOL_NX_OPTIN を指定し、ドライバー初期化関数 (DriverEntry または DllInitialize) から ExInitializeDriverRuntime(DrvRtPoolNxOptIn) を呼び出します。

POOL_NX_OPTIN_AUTO または POOL_NX_OPTIN のどちらを使用するかの選択は、ターゲットとするプラットフォームと作成するバイナリの数によって大きく異なります。 どちらのオプションでも、これら 2 つの型が (コンパイラまたは実行時に) NX に変更されます。 詳細については、トピックのリンクを参照してください。

次のいずれかの条件に該当する場合は、誤検知の警告が表示されることがあります。

  • ドライバー初期化関数は、ExInitializeDriverRuntime(DrvRtPoolNxOptIn) を呼び出す別の関数を呼び出します
  • DRIVER_LIBRARY を作成中で、POOL_NX_OPTIN を指定しましたが、初期化関数はありません。
  • 割り当ての種類を実行不可能な種類に変更します。

例 (POOL_NX_OPTIN_AUTO):

ソース ファイルの次の設定では、API 呼び出しで実行可能パラメーターを指定する必要がある場合に警告を許可します。

C_DEFINES=$(C_DEFINES)

ソース ファイル内の次の設定では、警告が回避されます。

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN_AUTO=1

例 (POOL_NX_OPTIN):

ソース ファイル内の次のコードでは、警告が生成されます。

C_DEFINES=$(C_DEFINES)

ソース ファイル内の次のコードでは、警告が回避されます。

C_DEFINES=$(C_DEFINES) -DPOOL_NX_OPTIN=1

DriverEntry() では、メモリ割り当てが行われる前に次の処理を行います。

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

    ExInitializeDriverRuntime( DrvRtPoolNxOptIn );
…

例 (割り当ての種類を変更する):

MM_PAGE_PRIORITY の種類では、優先度の種類に MdlMappingNoExecute フラグを追加することで、これを修正できます。 このコマンドは Windows 8 以降でのみサポートされます。

次のコードでは、警告が生成されます。

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority);

次のコードでは、警告が回避されます。

pPtr = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority | MdlMappingNoExecute);

例 (POOL_TYPE)

POOL_TYPE の種類の場合は、要求の種類を実行不可能なバージョンの種類に変更することで、これを修正できます。 このコマンドは Windows 8 以降でのみサポートされます。

次のコードでは、警告が生成されます。

ExAllocatePoolWithTag(NonPagedPool, numberOfBytes, 'xppn');

次のコードでは、警告が回避されます。

ExAllocatePoolWithTag(NonPagedPoolNx, numberOfBytes, 'xppn');

その他の特殊なケース:

ExInitializeNPagedLookasideList ルーチンに変更があり、実行不可能な非ページ プール メモリを指定できるようになりました。 たとえば、次のコードでは、この警告が生成されます。

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

次のコードでは、この警告が回避されます。

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

ページ保護に関連する欠陥の場合:

一部の API では、ページ保護を指定できます。ZwMapViewOfSection はその 1 つです。 このような場合は、実行不可能なバージョンの保護の種類を使用します。

変更:

  • 以下のいずれかの代替手段 または PAGE_EXECUTE に対する PAGE_NOACCESS
  • PAGE_READONLY に対する PAGE_EXECUTE_READ
  • PAGE_READWRITE に対する PAGE_EXECUTE_READWRITE
  • PAGE_WRITECOPY に対する PAGE_EXECUTE_WRITECOPY

次のコードでは、警告が生成されます。

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

次のコードでは、この警告が回避されます。

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

キャッシュの種類に関連する欠陥の場合:

一部の API は、キャッシュの種類に応じて実行可能なアクセス許可を持つメモリを割り当てます。 このような 2 つの API は、MmAllocateContiguousMemorySpecifyCacheMmAllocateContiguousMemorySpecifyCacheNode です。 キャッシュの種類として MmCached を使用する場合 (MEMORY_CACHING_TYPE を参照)、実行可能メモリが割り当てられます。 これを解決するには、別のキャッシュの種類を選択するか、キャッシュされたメモリが必要な場合は、API MmAllocateContiguousNodeMemory を使用します。

変更:

  • キャッシュされたメモリが必要ない場合、MmNonCached または MmWriteCombined への MmCached
  • キャッシュされたメモリが必要な場合、MmAllocateContiguousNodeMemory への API

次のコードでは、警告が生成されます。

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

次のコードでは、キャッシュされたメモリが必要ない場合、この警告が回避されます。

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

次のコードでは、警告が生成されます。

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

次のコードでは、キャッシュされたメモリが必要な場合、この警告が回避されます。

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

次のコードでは、キャッシュされたメモリが必要ない場合、代替 API を使用します。

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

禁止されている関数

禁止されている API 置換 根拠/注意事項
ExInitializeNPagedLookasideList()
  • フラグ パラメーターを POOL_NX_ALLOCATION に設定してください
  • または、POOL_NX_OPTIN_AUTO / POOL_NX_OPTIN メソッド (above) を使用します
MmAllocateContiguousMemorySpecifyCache() MmAllocateContiguousNodeMemory() 詳細については、上記を参照してください

禁止されているフラグ

禁止されているフラグ 置換 根拠/注意事項
MM_PAGE_PRIORITY

詳細については、上記を参照してください
POOL_NX_OPTIN_AUTO これにより、異なるバージョンの Windows 用の複数のバイナリの作成がサポートされます
POOL_NX_OPTIN(+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn)) これにより、異なるバージョンの Windows で実行される単一のバイナリがサポートされます
PagePriority / MdlMappingNoExecute これは Windows 8 以降で動作します
PAGE_EXECUTE PAGE_NOACCESS 詳細については、上記を参照してください
PAGE_EXECUTE_READ PAGE_READONLY
PAGE_EXECUTE_READWRITE PAGE_READWRITE
PAGE_EXECUTE_WRITECOPY PAGE_WRITECOPY

POOL_TYPE