https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0e01cbc6cdedc187b89bfed5331d64b2af46f503

commit 0e01cbc6cdedc187b89bfed5331d64b2af46f503
Author:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
AuthorDate: Tue Jun 4 17:21:03 2024 +0200
Commit:     Hermès Bélusca-Maïto <hermes.belusca-ma...@reactos.org>
CommitDate: Tue Jan 21 19:16:03 2025 +0100

    [NTOS:IO] IoVolumeDeviceToDosName(): Fix returned DosName buffer 
initialization (#6990)
    
    The VolumePath buffer returned by IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
    contains one string stored as a multi-NUL-terminated string, whose
    total length is given by its `MultiSzLength` member.
    
    The DosName UNICODE_STRING just returns the (single) string as a normal
    NUL-terminated string. So, we need to remove the two NUL-terminators
    from the `MultiSzLength` count to retrieve the correct length.
---
 ntoskrnl/io/iomgr/volume.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/ntoskrnl/io/iomgr/volume.c b/ntoskrnl/io/iomgr/volume.c
index 5d5614b4454..9a5915d2802 100644
--- a/ntoskrnl/io/iomgr/volume.c
+++ b/ntoskrnl/io/iomgr/volume.c
@@ -1367,7 +1367,7 @@ IoVolumeDeviceToDosName(
      * Even if MOUNTMGR_VOLUME_PATHS allows bigger name lengths
      * than MAXUSHORT, we can't use them, because we have to return
      * this in an UNICODE_STRING that stores length in a USHORT. */
-    Length = sizeof(VolumePath) + VolumePath.MultiSzLength;
+    Length = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + 
VolumePath.MultiSzLength;
     if (Length > MAXUSHORT)
     {
         Status = STATUS_INVALID_BUFFER_SIZE;
@@ -1407,13 +1407,14 @@ IoVolumeDeviceToDosName(
         goto ReleaseMemory;
     }
 
-    /* Set output string */
-    DosName->Length = (USHORT)VolumePathPtr->MultiSzLength;
-    DosName->MaximumLength = (USHORT)VolumePathPtr->MultiSzLength + 
sizeof(UNICODE_NULL);
-    /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
+    /* Set the output string. Discount the last two
+     * NUL-terminators from the multi-string length. */
+    DosName->Length = (USHORT)VolumePathPtr->MultiSzLength - 2 * 
sizeof(UNICODE_NULL);
+    DosName->MaximumLength = DosName->Length + sizeof(UNICODE_NULL);
+    /* Recycle our MOUNTMGR_VOLUME_PATHS as the output buffer
+     * and move the NUL-terminated string to the beginning */
     DosName->Buffer = (PWSTR)VolumePathPtr;
-    /* Move name at the begin, RtlMoveMemory is OK with overlapping */
-    RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, 
VolumePathPtr->MultiSzLength);
+    RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, DosName->Length);
     DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
 
     /* Don't release the buffer, just dereference the FO and return success */

Reply via email to