From fefb982d644f97975f92f35c3dd4b67ccfe378ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 30 Dec 2018 14:02:54 +0100 Subject: [PATCH] [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 a6132692ae0..5004938c099 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 */