[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.
This commit is contained in:
Pierre Schweitzer 2019-10-19 18:04:30 +02:00
parent 67d3fbdd97
commit a058e680b6
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -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)