Avoid an use-after-free in GetVolumeNameForRoot()
svn path=/trunk/; revision=76027
MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
MountPoint->DeviceNameLength = NtPathName.Length;
RtlCopyMemory((PVOID)((ULONG_PTR)MountPoint + sizeof(MOUNTMGR_MOUNT_POINT)), NtPathName.Buffer, NtPathName.Length);
MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
MountPoint->DeviceNameLength = NtPathName.Length;
RtlCopyMemory((PVOID)((ULONG_PTR)MountPoint + sizeof(MOUNTMGR_MOUNT_POINT)), NtPathName.Buffer, NtPathName.Length);
- RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
/* Allocate a dummy output buffer to probe for size */
MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(MOUNTMGR_MOUNT_POINTS));
if (MountPoints == NULL)
{
/* Allocate a dummy output buffer to probe for size */
MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(MOUNTMGR_MOUNT_POINTS));
if (MountPoints == NULL)
{
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
INVALID_HANDLE_VALUE);
if (MountMgrHandle == INVALID_HANDLE_VALUE)
{
INVALID_HANDLE_VALUE);
if (MountMgrHandle == INVALID_HANDLE_VALUE)
{
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
return FALSE;
if (MountPoints == NULL)
{
CloseHandle(MountMgrHandle);
if (MountPoints == NULL)
{
CloseHandle(MountMgrHandle);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
/* If the mount manager failed, just quit */
if (!Ret)
{
/* If the mount manager failed, just quit */
if (!Ret)
{
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
/* We couldn't find anything matching, return an error */
if (CurrentMntPt == MountPoints->NumberOfMountPoints)
{
/* We couldn't find anything matching, return an error */
if (CurrentMntPt == MountPoints->NumberOfMountPoints)
{
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
/* We found a matching volume, have we enough memory to return it? */
if (cchBufferLength * sizeof(WCHAR) < FoundVolumeLen + 2 * sizeof(WCHAR))
{
/* We found a matching volume, have we enough memory to return it? */
if (cchBufferLength * sizeof(WCHAR) < FoundVolumeLen + 2 * sizeof(WCHAR))
{
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return FALSE;
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return FALSE;
lpszVolumeName[FoundVolumeLen / sizeof(WCHAR) + 1] = UNICODE_NULL;
/* We're done! */
lpszVolumeName[FoundVolumeLen / sizeof(WCHAR) + 1] = UNICODE_NULL;
/* We're done! */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
return TRUE;
}
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
return TRUE;
}