https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fefb982d644f97975f92f3...
commit fefb982d644f97975f92f35c3dd4b67ccfe378ee Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sun Dec 30 14:02:54 2018 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Dec 30 15:26:42 2018 +0100
[NTOS] Don't use TAG_IO_NAME when calling ExFreePoolWithTag() for freeing FileObject->FileName.Buffer .
This may look strange, since this buffer is originally allocated using the TAG_IO_NAME tag. However, it happens that file-system drivers are allowed to re-allocate this buffer: this is what the MS' open-sourced CDFS driver does, see e.g. CdCommonCreate() and CdNormalizeFileNames() in cdfs/create.c .
This fixes a pool tag mismatch 'mNoI' != 'nFdC' BSOD when resources are freed when closing a file that has been opened with a relative name on a CDFS-mounted volume. --- ntoskrnl/io/iomgr/file.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c index a6132692ae..5004938c09 100644 --- a/ntoskrnl/io/iomgr/file.c +++ b/ntoskrnl/io/iomgr/file.c @@ -253,7 +253,12 @@ IopDoNameTransmogrify(IN PIRP Irp, { if (FileObject->FileName.Buffer) { - ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); + /* + * Don't use TAG_IO_NAME since the FileObject's FileName + * may have been re-allocated using a different tag + * by a filesystem. + */ + ExFreePoolWithTag(FileObject->FileName.Buffer, 0); }
FileObject->FileName.Buffer = NewBuffer; @@ -1060,11 +1065,16 @@ IopParseDevice(IN PVOID ParseObject, /* The driver failed to create the file */ if (!NT_SUCCESS(Status)) { - /* Check if we have a name */ + /* Check if we have a name and if so, free it */ if (FileObject->FileName.Length) { - /* Free it */ - ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); + /* + * Don't use TAG_IO_NAME since the FileObject's FileName + * may have been re-allocated using a different tag + * by a filesystem. + */ + ExFreePoolWithTag(FileObject->FileName.Buffer, 0); + FileObject->FileName.Buffer = NULL; FileObject->FileName.Length = 0; }
@@ -1112,6 +1122,11 @@ IopParseDevice(IN PVOID ParseObject, /* Release the old one */ if (CompleteName->Buffer != NULL) { + /* + * Don't use TAG_IO_NAME since the FileObject's FileName + * may have been re-allocated using a different tag + * by a filesystem. + */ ExFreePoolWithTag(CompleteName->Buffer, 0); }
@@ -1129,11 +1144,16 @@ IopParseDevice(IN PVOID ParseObject, } }
- /* Check if we have a name */ + /* Check if we have a name and if so, free it */ if (FileObject->FileName.Length) { - /* Free it */ + /* + * Don't use TAG_IO_NAME since the FileObject's FileName + * may have been re-allocated using a different tag + * by a filesystem. + */ ExFreePoolWithTag(FileObject->FileName.Buffer, 0); + FileObject->FileName.Buffer = NULL; FileObject->FileName.Length = 0; }
@@ -1427,8 +1447,13 @@ IopDeleteFile(IN PVOID ObjectBody) /* Clear the file name */ if (FileObject->FileName.Buffer) { - ExFreePoolWithTag(FileObject->FileName.Buffer, TAG_IO_NAME); - FileObject->FileName.Buffer = NULL; + /* + * Don't use TAG_IO_NAME since the FileObject's FileName + * may have been re-allocated using a different tag + * by a filesystem. + */ + ExFreePoolWithTag(FileObject->FileName.Buffer, 0); + FileObject->FileName.Buffer = NULL; }
/* Check if the FO had a completion port */