[MOUNTMGR] Fix some other bugs (#6990)

- Use FIELD_OFFSET to correct structure and member instead of hardcoding
  sizeof-s of fields until the member of interest.

- Fix a bug in MountMgrQueryDosVolumePath() where the FIELD_OFFSET used
  in the entry structure size validation was incorrect.

  FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceNameLength) is == 0 since
  DeviceNameLength is the first member of the MOUNTMGR_TARGET_NAME
  structure. The intended member was DeviceName.

  Addendum to commit f9f5a78715.
This commit is contained in:
Hermès Bélusca-Maïto 2025-01-19 22:32:25 +01:00
parent be97a36f25
commit e72a9a78b0
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -637,7 +637,8 @@ MountMgrNextDriveLetter(IN PDEVICE_EXTENSION DeviceExtension,
} }
DriveLetterTarget = (PMOUNTMGR_DRIVE_LETTER_TARGET)Irp->AssociatedIrp.SystemBuffer; DriveLetterTarget = (PMOUNTMGR_DRIVE_LETTER_TARGET)Irp->AssociatedIrp.SystemBuffer;
if (DriveLetterTarget->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) if (FIELD_OFFSET(MOUNTMGR_DRIVE_LETTER_TARGET, DeviceName) + DriveLetterTarget->DeviceNameLength >
Stack->Parameters.DeviceIoControl.InputBufferLength)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -842,14 +843,14 @@ MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension,
} }
/* Validate the entry structure size */ /* Validate the entry structure size */
if ((FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceNameLength) + Target->DeviceNameLength) > if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
Stack->Parameters.DeviceIoControl.InputBufferLength) Stack->Parameters.DeviceIoControl.InputBufferLength)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* Ensure we can at least return needed size */ /* Ensure we can at least return needed size */
if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz))
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -1007,11 +1008,10 @@ TryWithVolumeName:
/* At least, we will return our length */ /* At least, we will return our length */
Output->MultiSzLength = DeviceLength; Output->MultiSzLength = DeviceLength;
/* MOUNTMGR_VOLUME_PATHS is a string + a ULONG */ Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + DeviceLength;
Irp->IoStatus.Information = DeviceLength + sizeof(ULONG);
/* If we have enough room for copying the string */ /* If we have enough room for copying the string */
if (sizeof(ULONG) + DeviceLength <= Stack->Parameters.DeviceIoControl.OutputBufferLength) if (Irp->IoStatus.Information <= Stack->Parameters.DeviceIoControl.OutputBufferLength)
{ {
/* Copy it */ /* Copy it */
if (DeviceLength) if (DeviceLength)
@ -1031,7 +1031,7 @@ TryWithVolumeName:
{ {
/* Just return the size needed and leave */ /* Just return the size needed and leave */
FreePool(DeviceString); FreePool(DeviceString);
Irp->IoStatus.Information = sizeof(ULONG); Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz);
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
} }
} }
@ -1469,13 +1469,14 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
} }
/* Validate the entry structure size */ /* Validate the entry structure size */
if (Target->DeviceNameLength + FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) > Stack->Parameters.DeviceIoControl.InputBufferLength) if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
Stack->Parameters.DeviceIoControl.InputBufferLength)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* Ensure we can at least return needed size */ /* Ensure we can at least return needed size */
if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz))
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -1566,12 +1567,12 @@ MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension,
Output->MultiSzLength = Paths->MultiSzLength; Output->MultiSzLength = Paths->MultiSzLength;
/* Compute total length */ /* Compute total length */
OutputLength = Output->MultiSzLength + sizeof(ULONG); OutputLength = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + Output->MultiSzLength;
/* If it cannot fit, just return the size needed and leave */ /* If it cannot fit, just return the size needed and leave */
if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength) if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
{ {
Irp->IoStatus.Information = sizeof(ULONG); Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz);
FreePool(Paths); FreePool(Paths);
return STATUS_BUFFER_OVERFLOW; return STATUS_BUFFER_OVERFLOW;
} }
@ -1605,7 +1606,8 @@ MountMgrKeepLinksWhenOffline(IN PDEVICE_EXTENSION DeviceExtension,
} }
Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer; Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
Stack->Parameters.DeviceIoControl.InputBufferLength)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -1649,7 +1651,8 @@ MountMgrVolumeArrivalNotification(IN PDEVICE_EXTENSION DeviceExtension,
} }
Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer; Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength) if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
Stack->Parameters.DeviceIoControl.InputBufferLength)
{ {
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }