[NTOSKRNL] In IopQueryNameInternal(), enclose output copy in a SEH statement
authorPierre Schweitzer <pierre@reactos.org>
Wed, 3 Oct 2018 20:55:23 +0000 (22:55 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Wed, 3 Oct 2018 20:55:23 +0000 (22:55 +0200)
ntoskrnl/io/iomgr/file.c

index f8afc88..68a801f 100644 (file)
@@ -1975,142 +1975,147 @@ IopQueryNameInternal(IN PVOID ObjectBody,
     /* Get buffer pointer */
     p = (PWCHAR)(ObjectNameInfo + 1);
 
-    /* Copy the information */
-    if (QueryDosName && NoObCall)
+    _SEH2_TRY
     {
-        ASSERT(PreviousMode == KernelMode);
+        /* Copy the information */
+        if (QueryDosName && NoObCall)
+        {
+            ASSERT(PreviousMode == KernelMode);
 
-        /* Copy structure first */
-        RtlCopyMemory(ObjectNameInfo,
-                      LocalInfo,
-                      (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length));
-        /* Name then */
-        RtlCopyMemory(p, LocalInfo->Name.Buffer,
-                      (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION)));
+            /* Copy structure first */
+            RtlCopyMemory(ObjectNameInfo,
+                          LocalInfo,
+                          (Length >= LocalReturnLength ? sizeof(OBJECT_NAME_INFORMATION) : Length));
+            /* Name then */
+            RtlCopyMemory(p, LocalInfo->Name.Buffer,
+                          (Length >= LocalReturnLength ? LocalInfo->Name.Length : Length - sizeof(OBJECT_NAME_INFORMATION)));
 
-        if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
+            if (FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM)
+            {
+                ExFreePool(LocalInfo->Name.Buffer);
+            }
+        }
+        else
         {
-            ExFreePool(LocalInfo->Name.Buffer);
+            RtlCopyMemory(ObjectNameInfo,
+                          LocalInfo,
+                          (LocalReturnLength > Length) ?
+                          Length : LocalReturnLength);
         }
-    }
-    else
-    {
-        RtlCopyMemory(ObjectNameInfo,
-                      LocalInfo,
-                      (LocalReturnLength > Length) ?
-                      Length : LocalReturnLength);
-    }
 
-    /* Set buffer pointer */
-    ObjectNameInfo->Name.Buffer = p;
+        /* Set buffer pointer */
+        ObjectNameInfo->Name.Buffer = p;
 
-    /* Advance in buffer */
-    p += (LocalInfo->Name.Length / sizeof(WCHAR));
+        /* Advance in buffer */
+        p += (LocalInfo->Name.Length / sizeof(WCHAR));
 
-    /* Check if this already filled our buffer */
-    if (LocalReturnLength > Length)
-    {
-        /* Set the length mismatch to true, so that we can return
-         * the proper buffer size to the caller later
-         */
-        LengthMismatch = TRUE;
+        /* Check if this already filled our buffer */
+        if (LocalReturnLength > Length)
+        {
+            /* Set the length mismatch to true, so that we can return
+             * the proper buffer size to the caller later
+             */
+            LengthMismatch = TRUE;
 
-        /* Save the initial buffer length value */
-        *ReturnLength = LocalReturnLength;
-    }
+            /* Save the initial buffer length value */
+            *ReturnLength = LocalReturnLength;
+        }
 
-    /* Now get the file name buffer and check the length needed */
-    LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
-    FileLength = Length -
-                 LocalReturnLength +
-                 FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+        /* Now get the file name buffer and check the length needed */
+        LocalFileInfo = (PFILE_NAME_INFORMATION)LocalInfo;
+        FileLength = Length -
+                     LocalReturnLength +
+                     FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
 
-    /* Query the File name */
-    if (PreviousMode == KernelMode &&
-        BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
-    {
-        Status = IopGetFileInformation(FileObject,
-                                       LengthMismatch ? Length : FileLength,
-                                       FileNameInformation,
-                                       LocalFileInfo,
-                                       &LocalReturnLength);
-    }
-    else
-    {
-        Status = IoQueryFileInformation(FileObject,
-                                        FileNameInformation,
-                                        LengthMismatch ? Length : FileLength,
-                                        LocalFileInfo,
-                                        &LocalReturnLength);
-    }
-    if (NT_ERROR(Status))
-    {
-        /* Allow status that would mean it's not implemented in the storage stack */
-        if (Status != STATUS_INVALID_PARAMETER && Status != STATUS_INVALID_DEVICE_REQUEST &&
-            Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_INFO_CLASS)
+        /* Query the File name */
+        if (PreviousMode == KernelMode &&
+            BooleanFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO))
         {
-            ExFreePoolWithTag(LocalInfo, TAG_IO);
-            return Status;
+            Status = IopGetFileInformation(FileObject,
+                                           LengthMismatch ? Length : FileLength,
+                                           FileNameInformation,
+                                           LocalFileInfo,
+                                           &LocalReturnLength);
         }
-
-        /* In such case, zero output */
-        LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
-        LocalFileInfo->FileNameLength = 0;
-        LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
-    }
-    else
-    {
-        /* We'll at least return the name length */
-        if (LocalReturnLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
+        else
+        {
+            Status = IoQueryFileInformation(FileObject,
+                                            FileNameInformation,
+                                            LengthMismatch ? Length : FileLength,
+                                            LocalFileInfo,
+                                            &LocalReturnLength);
+        }
+        if (NT_ERROR(Status))
         {
+            /* Allow status that would mean it's not implemented in the storage stack */
+            if (Status != STATUS_INVALID_PARAMETER && Status != STATUS_INVALID_DEVICE_REQUEST &&
+                Status != STATUS_NOT_IMPLEMENTED && Status != STATUS_INVALID_INFO_CLASS)
+            {
+                _SEH2_LEAVE;
+            }
+
+            /* In such case, zero output */
             LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+            LocalFileInfo->FileNameLength = 0;
+            LocalFileInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
+        }
+        else
+        {
+            /* We'll at least return the name length */
+            if (LocalReturnLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName))
+            {
+                LocalReturnLength = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+            }
         }
-    }
 
-    /* If the provided buffer is too small, return the required size */
-    if (LengthMismatch)
-    {
-        /* Add the required length */
-        *ReturnLength += LocalFileInfo->FileNameLength;
+        /* If the provided buffer is too small, return the required size */
+        if (LengthMismatch)
+        {
+            /* Add the required length */
+            *ReturnLength += LocalFileInfo->FileNameLength;
 
-        /* Free the allocated buffer and return failure */
-        ExFreePoolWithTag(LocalInfo, TAG_IO);
-        return STATUS_BUFFER_OVERFLOW;
-    }
+            /* Free the allocated buffer and return failure */
+            Status = STATUS_BUFFER_OVERFLOW;
+            _SEH2_LEAVE;
+        }
 
-    /* Now calculate the new lengths left */
-    FileLength = LocalReturnLength -
-                 FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
-    LocalReturnLength = (ULONG)((ULONG_PTR)p -
-                                (ULONG_PTR)ObjectNameInfo +
-                                LocalFileInfo->FileNameLength);
+        /* Now calculate the new lengths left */
+        FileLength = LocalReturnLength -
+                     FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+        LocalReturnLength = (ULONG)((ULONG_PTR)p -
+                                    (ULONG_PTR)ObjectNameInfo +
+                                    LocalFileInfo->FileNameLength);
 
-    /* Don't copy the name if it's not valid */
-    if (LocalFileInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR)
-    {
-        /* Free the allocated buffer and return failure */
-        ExFreePoolWithTag(LocalInfo, TAG_IO);
-        return STATUS_OBJECT_PATH_INVALID;
-    }
+        /* Don't copy the name if it's not valid */
+        if (LocalFileInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR)
+        {
+            /* Free the allocated buffer and return failure */
+            Status = STATUS_OBJECT_PATH_INVALID;
+            _SEH2_LEAVE;
+        }
 
-    /* Write the Name and null-terminate it */
-    RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
-    p += (FileLength / sizeof(WCHAR));
-    *p = UNICODE_NULL;
-    LocalReturnLength += sizeof(UNICODE_NULL);
+        /* Write the Name and null-terminate it */
+        RtlCopyMemory(p, LocalFileInfo->FileName, FileLength);
+        p += (FileLength / sizeof(WCHAR));
+        *p = UNICODE_NULL;
+        LocalReturnLength += sizeof(UNICODE_NULL);
 
-    /* Return the length needed */
-    *ReturnLength = LocalReturnLength;
+        /* Return the length needed */
+        *ReturnLength = LocalReturnLength;
 
-    /* Setup the length and maximum length */
-    FileLength = (ULONG)((ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo);
-    ObjectNameInfo->Name.Length = (USHORT)FileLength -
-                                          sizeof(OBJECT_NAME_INFORMATION);
-    ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
-                                                 sizeof(UNICODE_NULL);
+        /* Setup the length and maximum length */
+        FileLength = (ULONG)((ULONG_PTR)p - (ULONG_PTR)ObjectNameInfo);
+        ObjectNameInfo->Name.Length = (USHORT)FileLength -
+                                              sizeof(OBJECT_NAME_INFORMATION);
+        ObjectNameInfo->Name.MaximumLength = (USHORT)ObjectNameInfo->Name.Length +
+                                                     sizeof(UNICODE_NULL);
+    }
+    _SEH2_FINALLY
+    {
+        /* Free buffer and return */
+        ExFreePoolWithTag(LocalInfo, TAG_IO);
+    } _SEH2_END;
 
-    /* Free buffer and return */
-    ExFreePoolWithTag(LocalInfo, TAG_IO);
     return Status;
 }