ReactOS 0.4.17-dev-1164-g974a446
ignorepooltag.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: KSE 'IgnoreFreePoolTag' shim implementation
5 * COPYRIGHT: Copyright 2026 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8/*
9 * Some drivers free memory with a different tag than it was allocated with.
10 * Windows only validates the tag when freeing protected pool, while checked
11 * builds of ReactOS validate it for every allocation and bugcheck with
12 * BAD_POOL_CALLER (0xC2, 0x0A).
13 *
14 * Example: the VMware SVGA 3D driver (vmx_svga.sys) frees 'vmGB' memory with
15 * the 'vmKM' tag when an OpenGL application exits (CORE-14623).
16 */
17
18#include <ntoskrnl.h>
19#include <initguid.h>
20
21#define NDEBUG
22#include <debug.h>
23
24DEFINE_GUID(KseIgnoreFreePoolTagGuid, 0x8d0ed225, 0x0892, 0x4efc, 0x9e, 0x72, 0x50, 0x89, 0x12, 0x42, 0x74, 0x53);
25
27
28static VOID NTAPI
30 _In_ PVOID P,
32{
33 VOID (NTAPI *OriginalFunction)(PVOID, ULONG);
34
36
37 /* Keep validating explicit frees of protected pool, like Windows does */
38 if (!(Tag & PROTECTED_POOL))
39 Tag = 0;
40
41 OriginalFunction(P, Tag);
42}
43
45 { KseHookFunction, { "ExFreePoolWithTag" }, (PVOID)(ULONG_PTR)ShimExFreePoolWithTag },
47};
48
52};
53
54KSE_SHIM KseIgnoreFreePoolTagShim = { sizeof(KSE_SHIM), &KseIgnoreFreePoolTagGuid, L"IgnoreFreePoolTag", NULL, NULL, NULL, KseIgnoreFreePoolTagCollections };
55
56CODE_SEG("INIT")
60{
62
64 if (!NT_SUCCESS(Status))
65 DPRINT1("KSE: Unable to register IgnoreFreePoolTag shim (0x%lx)\n", Status);
66
67 return Status;
68}
#define CODE_SEG(...)
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define P(row, col)
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:24
static VOID NTAPI ShimExFreePoolWithTag(_In_ PVOID P, _In_ ULONG Tag)
Definition: ignorepooltag.c:29
NTSTATUS NTAPI KseIgnoreFreePoolTagInitialize(VOID)
Definition: ignorepooltag.c:59
static KSE_HOOK KseIgnoreFreePoolTagHooksNT[]
Definition: ignorepooltag.c:44
KSE_SHIM KseIgnoreFreePoolTagShim
Definition: ignorepooltag.c:54
static KSE_HOOK_COLLECTION KseIgnoreFreePoolTagCollections[]
Definition: ignorepooltag.c:49
#define KseCollectionInvalid
Definition: kse.h:38
#define KseHookInvalid
Definition: kse.h:13
#define KseCollectionNtExport
Definition: kse.h:34
struct _KSE_SHIM KSE_SHIM
#define KseHookFunction
Definition: kse.h:11
NTSTATUS NTAPI KseRegisterShim(_In_ PKSE_SHIM Shim, _In_ PVOID Ignored, _In_ ULONG Flags)
Definition: kse.c:464
#define _In_
Definition: no_sal2.h:158
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
PKSE_HOOK HookArray
Definition: kse.h:44
Definition: kse.h:22
PVOID OriginalFunction
Definition: kse.h:30
Definition: kse.h:92
PKSE_HOOK_COLLECTION HookCollectionsArray
Definition: kse.h:99
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ UCXENDPOINT _In_ PVOID Tag
Definition: ucxendpoint.h:325
#define PROTECTED_POOL
Definition: extypes.h:349