sys: on Windows 8+ make Write buffer read-only

This commit is contained in:
Bill Zissimopoulos 2016-04-20 16:01:35 -07:00
parent f30a3ed7f3
commit 57793f9b9a
7 changed files with 40 additions and 9 deletions

View File

@ -729,7 +729,7 @@ NTSTATUS FspFsvolDirectoryControlPrepare(
MmBuildMdlForNonPagedPool(Mdl); MmBuildMdlForNonPagedPool(Mdl);
/* map the MDL into user-mode */ /* map the MDL into user-mode */
Result = FspMapLockedPagesInUserMode(Mdl, &Address); Result = FspMapLockedPagesInUserMode(Mdl, &Address, 0);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (0 != Mdl) if (0 != Mdl)

View File

@ -165,14 +165,17 @@ NTSTATUS DriverEntry(
static VOID FspDriverMultiVersionInitialize(VOID) static VOID FspDriverMultiVersionInitialize(VOID)
{ {
UNICODE_STRING Name;
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7)) if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7))
{ {
UNICODE_STRING Name;
RtlInitUnicodeString(&Name, L"CcCoherencyFlushAndPurgeCache"); RtlInitUnicodeString(&Name, L"CcCoherencyFlushAndPurgeCache");
FspMvCcCoherencyFlushAndPurgeCache = FspMvCcCoherencyFlushAndPurgeCache =
(FSP_MV_CcCoherencyFlushAndPurgeCache *)(UINT_PTR)MmGetSystemRoutineAddress(&Name); (FSP_MV_CcCoherencyFlushAndPurgeCache *)(UINT_PTR)MmGetSystemRoutineAddress(&Name);
} }
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8))
FspMvMdlMappingNoWrite = MdlMappingNoWrite;
} }
#if defined(FSP_UNLOAD) #if defined(FSP_UNLOAD)
@ -201,3 +204,4 @@ FAST_IO_DISPATCH FspFastIoDispatch;
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks; CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
ULONG FspMvMdlMappingNoWrite = 0;

View File

@ -419,7 +419,7 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes, NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes,
BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext); BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext);
NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes); NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
@ -1037,5 +1037,6 @@ extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
extern ERESOURCE FspDeviceGlobalResource; extern ERESOURCE FspDeviceGlobalResource;
extern WCHAR FspFileDescDirectoryPatternMatchAll[]; extern WCHAR FspFileDescDirectoryPatternMatchAll[];
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
extern ULONG FspMvMdlMappingNoWrite;
#endif #endif

View File

@ -300,7 +300,8 @@ NTSTATUS FspFsvolReadPrepare(
} }
/* map the MDL into user-mode */ /* map the MDL into user-mode */
Result = FspMapLockedPagesInUserMode(0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address); Result = FspMapLockedPagesInUserMode(
0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address, 0);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (0 != SafeMdl) if (0 != SafeMdl)

View File

@ -15,7 +15,7 @@ static NTSTATUS FspSendSetInformationIrpCompletion(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0); PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes, NTSTATUS FspCcInitializeCacheMap(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes,
BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext); BOOLEAN PinAccess, PCACHE_MANAGER_CALLBACKS Callbacks, PVOID CallbackContext);
NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes); NTSTATUS FspCcSetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
@ -355,13 +355,14 @@ NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress) NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags)
{ {
PAGED_CODE(); PAGED_CODE();
try try
{ {
*PAddress = MmMapLockedPagesSpecifyCache(Mdl, UserMode, MmCached, 0, FALSE, NormalPagePriority); *PAddress = MmMapLockedPagesSpecifyCache(Mdl, UserMode, MmCached, 0, FALSE,
NormalPagePriority | ExtraPriorityFlags);
return 0 != *PAddress ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; return 0 != *PAddress ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
} }
except (EXCEPTION_EXECUTE_HANDLER) except (EXCEPTION_EXECUTE_HANDLER)

View File

@ -357,7 +357,8 @@ NTSTATUS FspFsvolWritePrepare(
} }
/* map the MDL into user-mode */ /* map the MDL into user-mode */
Result = FspMapLockedPagesInUserMode(0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address); Result = FspMapLockedPagesInUserMode(
0 != SafeMdl ? SafeMdl->Mdl : Irp->MdlAddress, &Address, FspMvMdlMappingNoWrite);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (0 != SafeMdl) if (0 != SafeMdl)

View File

@ -10,6 +10,14 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
/*
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
* a check for the Write buffer to ensure that it is read-only.
*/
#if !defined(NDEBUG)
#define DEBUG_BUFFER_CHECK
#endif
#define MEMFS_SECTOR_SIZE 512 #define MEMFS_SECTOR_SIZE 512
#define MEMFS_SECTORS_PER_ALLOCATION_UNIT 1 #define MEMFS_SECTORS_PER_ALLOCATION_UNIT 1
@ -501,6 +509,21 @@ static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem,
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo) PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
#if defined(DEBUG_BUFFER_CHECK)
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
for (PUINT8 P = (PUINT8)Buffer, EndP = P + Length; EndP > P; P += SystemInfo.dwPageSize)
__try
{
*P = *P | 0;
assert(0);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
/* ignore! */
}
#endif
MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
UINT64 EndOffset; UINT64 EndOffset;