[FASTFAT] Fix create for DOT and DOT-DOT leaving bad directory entry (#3241)

This commit is contained in:
Doug Lyons 2020-09-26 17:39:15 -05:00 committed by Stanislav Motylkov
parent ea3973f12e
commit 79794b524c
No known key found for this signature in database
GPG key ID: AFE513258CBA9E92
4 changed files with 28 additions and 7 deletions

View file

@ -360,9 +360,7 @@ VfatOpenFile(
return STATUS_CANNOT_DELETE; return STATUS_CANNOT_DELETE;
} }
if ((vfatFCBIsRoot(Fcb) || if ((vfatFCBIsRoot(Fcb) || IsDotOrDotDot(&Fcb->LongNameU)) &&
(Fcb->LongNameU.Length == sizeof(WCHAR) && Fcb->LongNameU.Buffer[0] == L'.') ||
(Fcb->LongNameU.Length == 2 * sizeof(WCHAR) && Fcb->LongNameU.Buffer[0] == L'.' && Fcb->LongNameU.Buffer[1] == L'.')) &&
BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE)) BooleanFlagOn(RequestedOptions, FILE_DELETE_ON_CLOSE))
{ {
// we cannot delete a '.', '..' or the root directory // we cannot delete a '.', '..' or the root directory
@ -791,6 +789,13 @@ VfatCreateFile(
Attributes |= FILE_ATTRIBUTE_ARCHIVE; Attributes |= FILE_ATTRIBUTE_ARCHIVE;
} }
vfatSplitPathName(&PathNameU, NULL, &FileNameU); vfatSplitPathName(&PathNameU, NULL, &FileNameU);
if (IsDotOrDotDot(&FileNameU))
{
vfatReleaseFCB(DeviceExt, ParentFcb);
vfatAddToStat(DeviceExt, Fat.FailedCreates, 1);
return STATUS_OBJECT_NAME_INVALID;
}
Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions, Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
Attributes, NULL); Attributes, NULL);
vfatReleaseFCB(DeviceExt, ParentFcb); vfatReleaseFCB(DeviceExt, ParentFcb);

View file

@ -380,9 +380,7 @@ VfatSetDispositionInformation(
return STATUS_CANNOT_DELETE; return STATUS_CANNOT_DELETE;
} }
if (vfatFCBIsRoot(FCB) || if (vfatFCBIsRoot(FCB) || IsDotOrDotDot(&FCB->LongNameU))
(FCB->LongNameU.Length == sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.') ||
(FCB->LongNameU.Length == 2 * sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.' && FCB->LongNameU.Buffer[1] == L'.'))
{ {
/* we cannot delete a '.', '..' or the root directory */ /* we cannot delete a '.', '..' or the root directory */
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
@ -804,6 +802,12 @@ VfatSetRenameInformation(
vfatSplitPathName(&NewName, &NewPath, &NewFile); vfatSplitPathName(&NewName, &NewPath, &NewFile);
DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile); DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
if (IsDotOrDotDot(&NewFile))
{
Status = STATUS_OBJECT_NAME_INVALID;
goto Cleanup;
}
if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead)) if (vfatFCBIsDirectory(FCB) && !IsListEmpty(&FCB->ParentListHead))
{ {
if (IsThereAChildOpened(FCB)) if (IsThereAChildOpened(FCB))

View file

@ -3,7 +3,8 @@
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/string.c * FILE: drivers/fs/vfat/string.c
* PURPOSE: VFAT Filesystem * PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com) * PROGRAMMERS: Jason Filby (jasonfilby@yahoo.com)
* Doug Lyons (douglyons at douglyons dot com)
* *
*/ */
@ -24,3 +25,10 @@ vfatIsLongIllegal(
{ {
return wcschr(long_illegals, c) ? TRUE : FALSE; return wcschr(long_illegals, c) ? TRUE : FALSE;
} }
BOOLEAN
IsDotOrDotDot(PCUNICODE_STRING Name)
{
return ((Name->Length == sizeof(WCHAR) && Name->Buffer[0] == L'.') ||
(Name->Length == 2 * sizeof(WCHAR) && Name->Buffer[0] == L'.' && Name->Buffer[1] == L'.'));
}

View file

@ -1221,6 +1221,10 @@ BOOLEAN
vfatIsLongIllegal( vfatIsLongIllegal(
WCHAR c); WCHAR c);
BOOLEAN
IsDotOrDotDot(
PCUNICODE_STRING Name);
/* volume.c */ /* volume.c */
NTSTATUS NTSTATUS