Description
In order to create a new NT object, kernel-mode code does something like the following:
Status = ObCreateObject(..., (PVOID*)&Object);
|
if (NT_SUCCESS(Status))
|
{
|
// initialize fields on "Object"
|
Object->Field1 = 1234;
|
// ...
|
Status = ObInsertObject(Object, ..., &Handle);
|
if (NT_SUCCESS(Status))
|
{
|
*UserHandle = Handle;
|
}
|
}
|
return Status;
|
Note that in the case where ObInsertObject fails, the function automatically dereferences the object, so it is not necessary for the calling code to do this (nor should Object be accessed in any other ways in the case where ObInsertObject fails). Note that dereferencing a different object in this case may still make sense.
Looking at all callers of ObInsertObject, we have a few places where the caller incorrectly makes such a call to ObDereferenceObject.
Please review all call sites and fix the ones that have this bug: https://git.reactos.org/?p=reactos.git&a=search&h=HEAD&st=grep&s=ObInsertObject
A straightforward example of the bug (from MmCreatePhysicalMemorySection in ntoskrnl/mm/section.c):
2242 Status = ObInsertObject(PhysSection,
|
2243 NULL,
|
2244 SECTION_ALL_ACCESS,
|
2245 0,
|
2246 NULL,
|
2247 &Handle);
|
2248 if (!NT_SUCCESS(Status))
|
2249 {
|
2250 ObDereferenceObject(PhysSection);
|
2251 return Status;
|
2252 }
|
2253 ObCloseHandle(Handle, KernelMode);
|
2254
|
2255 return STATUS_SUCCESS;
|
In this failure case, PhysSection will be dereferenced twice (once by ObInsertObject and once by MmCreatePhysicalMemorySection)..