https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0e01cbc6cdedc187b89bf…
commit 0e01cbc6cdedc187b89bfed5331d64b2af46f503
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Tue Jun 4 17:21:03 2024 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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 */