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 */