From a058e680b662ad4aca76e1fe4803fe033c124aa2 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 19 Oct 2019 18:04:30 +0200 Subject: [PATCH] [MOUNTMGR] Don't kill Mm when a device has several symlinks On preflight to compute output size, device name & unique ID were counted only once per device. Then, on copy, these two were copied on every MOUNTMGR_MOUNT_POINT structure. This is counter efficient (data duplication) but also, it was overruning the output buffer, since the preflight was not expecting these extra copies. --- drivers/filters/mountmgr/point.c | 55 ++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/filters/mountmgr/point.c b/drivers/filters/mountmgr/point.c index a2469b0de82..38260a57c2a 100644 --- a/drivers/filters/mountmgr/point.c +++ b/drivers/filters/mountmgr/point.c @@ -241,11 +241,12 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension, NTSTATUS Status; PIO_STACK_LOCATION Stack; UNICODE_STRING DeviceName; - ULONG TotalSize, TotalSymLinks; PMOUNTMGR_MOUNT_POINTS MountPoints; PDEVICE_INFORMATION DeviceInformation; PLIST_ENTRY DeviceEntry, SymlinksEntry; PSYMLINK_INFORMATION SymlinkInformation; + USHORT UniqueIdLength, DeviceNameLength; + ULONG TotalSize, TotalSymLinks, UniqueIdOffset, DeviceNameOffset; /* If we got a symbolic link, query device */ if (SymbolicName) @@ -384,6 +385,26 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension, } } + /* Save our information about shared data */ + UniqueIdOffset = TotalSize; + UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength; + DeviceNameOffset = TotalSize + UniqueIdLength; + DeviceNameLength = DeviceInformation->DeviceName.Length; + + /* Initialize first symlink */ + MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset; + MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength; + MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset; + MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength; + + /* And copy data */ + RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + UniqueIdOffset), + DeviceInformation->UniqueId->UniqueId, UniqueIdLength); + RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + DeviceNameOffset), + DeviceInformation->DeviceName.Buffer, DeviceNameLength); + + TotalSize += DeviceInformation->UniqueId->UniqueIdLength + DeviceInformation->DeviceName.Length; + /* Now we've got it, but all the data */ for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink; SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead); @@ -391,27 +412,33 @@ QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension, { SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry); + /* First, set shared data */ + + /* Only put UniqueID if online */ + if (SymlinkInformation->Online) + { + MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset; + MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength; + } + else + { + MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = 0; + MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = 0; + } + + MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset; + MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength; + + /* And now, copy specific symlink info */ MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset = TotalSize; MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameLength = SymlinkInformation->Name.Length; - MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = SymlinkInformation->Name.Length + - TotalSize; - MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength; - MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = SymlinkInformation->Name.Length + - DeviceInformation->UniqueId->UniqueIdLength + - TotalSize; - MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceInformation->DeviceName.Length; RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset), SymlinkInformation->Name.Buffer, SymlinkInformation->Name.Length); - RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset), - DeviceInformation->UniqueId->UniqueId, DeviceInformation->UniqueId->UniqueIdLength); - RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset), - DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length); /* Update counters */ TotalSymLinks++; - TotalSize += SymlinkInformation->Name.Length + DeviceInformation->UniqueId->UniqueIdLength + - DeviceInformation->DeviceName.Length; + TotalSize += SymlinkInformation->Name.Length; } if (UniqueId || SymbolicName)