Author: rharabien Date: Fri Oct 21 13:21:56 2011 New Revision: 54222
URL: http://svn.reactos.org/svn/reactos?rev=54222&view=rev Log: [FASTFAT] - Fix memory corruption if long file name entry is invalid. - Minor improvements.
See issue #6546 for more details.
Modified: trunk/reactos/drivers/filesystems/fastfat/direntry.c trunk/reactos/drivers/filesystems/fastfat/fcb.c
Modified: trunk/reactos/drivers/filesystems/fastfat/direntry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat... ============================================================================== --- trunk/reactos/drivers/filesystems/fastfat/direntry.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat/direntry.c [iso-8859-1] Fri Oct 21 13:21:56 2011 @@ -181,7 +181,8 @@ BOOLEAN Valid = TRUE; BOOLEAN Back = FALSE;
- DirContext->LongNameU.Buffer[0] = 0; + DirContext->LongNameU.Length = 0; + DirContext->LongNameU.Buffer[0] = UNICODE_NULL;
FileOffset.u.HighPart = 0; FileOffset.u.LowPart = ROUND_DOWN(DirContext->DirIndex * sizeof(FAT_DIR_ENTRY), PAGE_SIZE); @@ -304,13 +305,29 @@ 6, longNameEntry->name5_10, 2, longNameEntry->name11_12);
- index = (longNameEntry->id & 0x1f) - 1; - dirMap |= 1 << index; - pName = DirContext->LongNameU.Buffer + 13 * index; - - RtlCopyMemory(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR)); - RtlCopyMemory(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR)); - RtlCopyMemory(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR)); + index = longNameEntry->id & 0x3f; // Note: it can be 0 for corrupted FS + + /* Make sure index is valid and we have enaugh space in buffer + (we count one char for \0) */ + if (index > 0 && + index * 13 < DirContext->LongNameU.MaximumLength / sizeof(WCHAR)) + { + index--; // make index 0 based + dirMap |= 1 << index; + + pName = DirContext->LongNameU.Buffer + index * 13; + RtlCopyMemory(pName, longNameEntry->name0_4, 5 * sizeof(WCHAR)); + RtlCopyMemory(pName + 5, longNameEntry->name5_10, 6 * sizeof(WCHAR)); + RtlCopyMemory(pName + 11, longNameEntry->name11_12, 2 * sizeof(WCHAR)); + + if (longNameEntry->id & 0x40) + { + /* It's last LFN entry. Terminate filename with \0 */ + pName[13] = UNICODE_NULL; + } + } + else + DPRINT1("Long name entry has invalid index: %x!\n", longNameEntry->id);
DPRINT (" longName: [%S]\n", DirContext->LongNameU.Buffer);
@@ -372,22 +389,26 @@ } }
+ /* Make sure filename is NULL terminate and calculate length */ + DirContext->LongNameU.Buffer[DirContext->LongNameU.MaximumLength / sizeof(WCHAR) - 1] + = UNICODE_NULL; DirContext->LongNameU.Length = wcslen(DirContext->LongNameU.Buffer) * sizeof(WCHAR); + + /* Init short name */ vfat8Dot3ToString(&DirContext->DirEntry.Fat, &DirContext->ShortNameU);
+ /* If we found no LFN, use short name as long */ if (DirContext->LongNameU.Length == 0) - { RtlCopyUnicodeString(&DirContext->LongNameU, &DirContext->ShortNameU); - }
return STATUS_SUCCESS; }
NTSTATUS FATXGetNextDirEntry(PVOID * pContext, - PVOID * pPage, + PVOID * pPage, IN PVFATFCB pDirFcb, - PVFAT_DIRENTRY_CONTEXT DirContext, - BOOLEAN First) + PVFAT_DIRENTRY_CONTEXT DirContext, + BOOLEAN First) { LARGE_INTEGER FileOffset; PFATX_DIR_ENTRY fatxDirEntry; @@ -405,7 +426,7 @@ { DirContext->ShortNameU.Buffer[0] = 0; DirContext->ShortNameU.Length = 0; - DirContext->LongNameU.Buffer[0] = L'.'; + wcscpy(DirContext->LongNameU.Buffer, L"."); DirContext->LongNameU.Length = sizeof(WCHAR); RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY)); DirContext->DirEntry.FatX.Filename[0] = '.'; @@ -417,7 +438,7 @@ { DirContext->ShortNameU.Buffer[0] = 0; DirContext->ShortNameU.Length = 0; - DirContext->LongNameU.Buffer[0] = DirContext->LongNameU.Buffer[1] = L'.'; + wcscpy(DirContext->LongNameU.Buffer, L".."); DirContext->LongNameU.Length = 2 * sizeof(WCHAR); RtlCopyMemory(&DirContext->DirEntry.FatX, &pDirFcb->entry.FatX, sizeof(FATX_DIR_ENTRY)); DirContext->DirEntry.FatX.Filename[0] = DirContext->DirEntry.FatX.Filename[1] = '.';
Modified: trunk/reactos/drivers/filesystems/fastfat/fcb.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat... ============================================================================== --- trunk/reactos/drivers/filesystems/fastfat/fcb.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/fastfat/fcb.c [iso-8859-1] Fri Oct 21 13:21:56 2011 @@ -604,8 +604,7 @@ DPRINT (" Index:%d longName:%wZ\n", DirContext.DirIndex, &DirContext.LongNameU); - DirContext.LongNameU.Buffer[DirContext.LongNameU.Length / sizeof(WCHAR)] = 0; - DirContext.ShortNameU.Buffer[DirContext.ShortNameU.Length / sizeof(WCHAR)] = 0; + if (!ENTRY_VOLUME(pDeviceExt, &DirContext.DirEntry)) { FoundLong = RtlEqualUnicodeString(FileToFindU, &DirContext.LongNameU, TRUE);