Author: fireball
Date: Mon Nov 17 05:25:36 2008
New Revision: 37393
URL:
http://svn.reactos.org/svn/reactos?rev=37393&view=rev
Log:
- FASTFAT: when querying file name information, fill in the whole buffer provided by the
caller, even if filename does not fully fit (driver by Microsoft(R) does the same). Also,
return the actual amount of data written in IoSb.Information, even in case of buffer
overflow result.
- CDFS: Fix a guaranteed buffer overwrite when zero-terminating a filename. Also apply the
same fixes described above.
Modified:
trunk/reactos/drivers/filesystems/cdfs/finfo.c
trunk/reactos/drivers/filesystems/fastfat/finfo.c
Modified: trunk/reactos/drivers/filesystems/cdfs/finfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/cdfs/f…
==============================================================================
--- trunk/reactos/drivers/filesystems/cdfs/finfo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/cdfs/finfo.c [iso-8859-1] Mon Nov 17 05:25:36 2008
@@ -145,23 +145,38 @@
PULONG BufferLength)
{
ULONG NameLength;
+ ULONG BytesToCopy;
DPRINT("CdfsGetNameInformation() called\n");
ASSERT(NameInfo != NULL);
ASSERT(Fcb != NULL);
+ /* If buffer can't hold at least the file name length, bail out */
+ if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
+ return STATUS_BUFFER_OVERFLOW;
+
+ /* Calculate file name length in bytes */
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
NameInfo->FileNameLength = NameLength;
- if (*BufferLength < (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + NameLength))
+
+ /* Calculate amount of bytes to copy not to overflow the buffer */
+ BytesToCopy = min(NameLength,
+ *BufferLength - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]));
+
+ /* Fill in the bytes */
+ RtlCopyMemory(NameInfo->FileName, Fcb->PathName, BytesToCopy);
+
+ /* Check if we could write more but are not able to */
+ if (*BufferLength < NameLength + FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
+ {
+ /* Return number of bytes written */
+ *BufferLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + BytesToCopy;
return STATUS_BUFFER_OVERFLOW;
-
- RtlCopyMemory(NameInfo->FileName,
- Fcb->PathName,
- NameLength + sizeof(WCHAR));
-
- *BufferLength -=
- (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + NameLength);
+ }
+
+ /* We filled up as many bytes, as needed */
+ *BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + NameLength);
return STATUS_SUCCESS;
}
@@ -395,7 +410,7 @@
}
Irp->IoStatus.Status = Status;
- if (NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
Irp->IoStatus.Information =
Stack->Parameters.QueryFile.Length - BufferLength;
else
Modified: trunk/reactos/drivers/filesystems/fastfat/finfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/finfo.c [iso-8859-1] Mon Nov 17 05:25:36
2008
@@ -338,15 +338,33 @@
* FUNCTION: Retrieve the file name information
*/
{
+ ULONG BytesToCopy;
ASSERT(NameInfo != NULL);
ASSERT(FCB != NULL);
+ /* If buffer can't hold at least the file name length, bail out */
+ if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
+ return STATUS_BUFFER_OVERFLOW;
+
+ /* Save file name length, and as much file len, as buffer length allows */
NameInfo->FileNameLength = FCB->PathNameU.Length;
- if (*BufferLength < FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) +
FCB->PathNameU.Length)
+
+ /* Calculate amount of bytes to copy not to overflow the buffer */
+ BytesToCopy = min(FCB->PathNameU.Length,
+ *BufferLength - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]));
+
+ /* Fill in the bytes */
+ RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer, BytesToCopy);
+
+ /* Check if we could write more but are not able to */
+ if (*BufferLength < FCB->PathNameU.Length + FIELD_OFFSET(FILE_NAME_INFORMATION,
FileName[0]))
+ {
+ /* Return number of bytes written */
+ *BufferLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) + BytesToCopy;
return STATUS_BUFFER_OVERFLOW;
-
- RtlCopyMemory(NameInfo->FileName, FCB->PathNameU.Buffer,
FCB->PathNameU.Length);
-
+ }
+
+ /* We filled up as many bytes, as needed */
*BufferLength -= (FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]) +
FCB->PathNameU.Length);
return STATUS_SUCCESS;
@@ -749,7 +767,7 @@
FILE_INFORMATION_CLASS FileInformationClass;
PVFATFCB FCB = NULL;
- NTSTATUS RC = STATUS_SUCCESS;
+ NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
@@ -780,44 +798,44 @@
switch (FileInformationClass)
{
case FileStandardInformation:
- RC = VfatGetStandardInformation(FCB,
+ Status = VfatGetStandardInformation(FCB,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
- RC = VfatGetPositionInformation(IrpContext->FileObject,
+ Status = VfatGetPositionInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
- RC = VfatGetBasicInformation(IrpContext->FileObject,
+ Status = VfatGetBasicInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileNameInformation:
- RC = VfatGetNameInformation(IrpContext->FileObject,
+ Status = VfatGetNameInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation:
- RC = VfatGetInternalInformation(FCB,
+ Status = VfatGetInternalInformation(FCB,
SystemBuffer,
&BufferLength);
break;
case FileNetworkOpenInformation:
- RC = VfatGetNetworkOpenInformation(FCB,
+ Status = VfatGetNetworkOpenInformation(FCB,
IrpContext->DeviceExt,
SystemBuffer,
&BufferLength);
break;
case FileAllInformation:
- RC = VfatGetAllInformation(IrpContext->FileObject,
+ Status = VfatGetAllInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
@@ -825,7 +843,7 @@
break;
case FileEaInformation:
- RC = VfatGetEaInformation(IrpContext->FileObject,
+ Status = VfatGetEaInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
@@ -833,18 +851,18 @@
break;
case FileAlternateNameInformation:
- RC = STATUS_NOT_IMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
break;
default:
- RC = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
}
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}
- IrpContext->Irp->IoStatus.Status = RC;
- if (NT_SUCCESS(RC))
+ IrpContext->Irp->IoStatus.Status = Status;
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)
IrpContext->Irp->IoStatus.Information =
IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
else
@@ -852,7 +870,7 @@
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
- return RC;
+ return Status;
}
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)