From c62229b9676f1e4196cd735b8d8819812305e5a0 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sat, 17 Aug 2002 14:14:20 +0000 Subject: [PATCH] 2002-08-17 David Welch * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): Ensure the process isn't freed in the middle of our operations. 2002-08-17 David Welch * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): Fixed. svn path=/trunk/; revision=3336 --- reactos/ChangeLog | 9 ++++++ reactos/drivers/fs/vfat/finfo.c | 51 +++++++++++++++++---------------- reactos/ntoskrnl/mm/rmap.c | 27 +++++++++++++++-- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 32d5fcb1440..018a458fdb0 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,12 @@ +2002-08-17 David Welch + + * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): Ensure the + process isn't freed in the middle of our operations. + +2002-08-17 David Welch + + * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): Fixed. + 2002-08-17 David Welch * ntoskrnl/ps/create.c (PiDeleteThread): Don't dereference diff --git a/reactos/drivers/fs/vfat/finfo.c b/reactos/drivers/fs/vfat/finfo.c index 76e6d93569a..c5560db6ae5 100644 --- a/reactos/drivers/fs/vfat/finfo.c +++ b/reactos/drivers/fs/vfat/finfo.c @@ -1,4 +1,4 @@ -/* $Id: finfo.c,v 1.15 2002/08/14 20:58:31 dwelch Exp $ +/* $Id: finfo.c,v 1.16 2002/08/17 14:14:19 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -351,14 +351,15 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, PLARGE_INTEGER AllocationSize) { ULONG OldSize; + ULONG FirstCluster; ULONG Cluster; - ULONG Offset; + ULONG i; NTSTATUS Status; PDEVICE_EXTENSION DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster; ULONG NewSize = AllocationSize->u.LowPart; - ULONG NextCluster; + ULONG PreviousCluster; OldSize = Fcb->entry.FileSize; if (OldSize == AllocationSize->u.LowPart) @@ -373,30 +374,36 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, if (DeviceExt->FatInfo.FatType == FAT32) { - Cluster = Fcb->entry.FirstCluster + Fcb->entry.FirstClusterHigh * 65536; + FirstCluster = Fcb->entry.FirstCluster + + Fcb->entry.FirstClusterHigh * 65536; } else { - Cluster = Fcb->entry.FirstCluster; + FirstCluster = Fcb->entry.FirstCluster; } + Cluster = FirstCluster; if (OldSize > NewSize && ROUND_UP(OldSize, ClusterSize) > ROUND_DOWN(NewSize, ClusterSize)) { /* Seek to the new end of the file. */ - Offset = 0; - while (Cluster != 0xffffffff && Cluster > 1 && Offset <= NewSize) + for (i = 0; i < (NewSize / ClusterSize); i++) { - Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE); - Cluster = NextCluster; - Offset += ClusterSize; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE); + } + /* Terminate the FAT chain at this point. */ + if (NewSize > 0) + { + PreviousCluster = Cluster; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE); + WriteCluster (DeviceExt, PreviousCluster, 0xFFFFFFFF); } /* Free everything beyond this point. */ while (Cluster != 0xffffffff && Cluster > 1) { - Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE); - WriteCluster (DeviceExt, Cluster, 0xFFFFFFFF); - Cluster = NextCluster; + PreviousCluster = Cluster; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, FALSE); + WriteCluster (DeviceExt, PreviousCluster, 0); } if (NewSize == 0) { @@ -408,21 +415,17 @@ VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject, ROUND_UP(NewSize, ClusterSize) > ROUND_DOWN(OldSize, ClusterSize)) { /* Seek to the new end of the file. */ - Offset = 0; if (OldSize == 0) { - assert(Cluster == 0); - Status = GetNextCluster (DeviceExt, 0, &NextCluster, TRUE); - Fcb->entry.FirstCluster = (NextCluster & 0x0000FFFF) >> 0; - Fcb->entry.FirstClusterHigh = (NextCluster & 0xFFFF0000) >> 16; - Cluster = NextCluster; - Offset += ClusterSize; + assert(FirstCluster == 0); + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, TRUE); + FirstCluster = Cluster; + Fcb->entry.FirstCluster = (FirstCluster & 0x0000FFFF) >> 0; + Fcb->entry.FirstClusterHigh = (FirstCluster & 0xFFFF0000) >> 16; } - while (Cluster != 0xffffffff && Cluster > 1 && Offset <= NewSize) + for (i = 0; i < (NewSize / ClusterSize); i++) { - Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, TRUE); - Cluster = NextCluster; - Offset += ClusterSize; + Status = NextCluster (DeviceExt, Fcb, FirstCluster, &Cluster, TRUE); } } diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index f592b723c4d..f2952dad9e4 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: rmap.c,v 1.8 2002/08/14 20:58:36 dwelch Exp $ +/* $Id: rmap.c,v 1.9 2002/08/17 14:14:20 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -69,6 +69,10 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) LARGE_INTEGER Offset; NTSTATUS Status; + /* + * Check that the address still has a valid rmap; then reference the + * process so it isn't freed while we are working. + */ ExAcquireFastMutex(&RmapListLock); entry = MmGetRmapListHeadPage(PhysicalAddress); if (entry == NULL) @@ -82,10 +86,22 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) { KeBugCheck(0); } - + ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); ExReleaseFastMutex(&RmapListLock); + + /* + * Lock the address space; then check that the address we are using + * still corresponds to a valid memory area (the page might have been + * freed or paged out after we read the rmap entry.) + */ MmLockAddressSpace(&Process->AddressSpace); MemoryArea = MmOpenMemoryAreaByAddress(&Process->AddressSpace, Address); + if (MemoryArea == NULL) + { + ObDereferenceObject(Process); + return(STATUS_UNSUCCESSFUL); + } + Type = MemoryArea->Type; if (Type == MEMORY_AREA_SECTION_VIEW) { @@ -104,6 +120,8 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) KeBugCheck(0); } + ObDereferenceObject(Process); + if (PageOp->Thread != PsGetCurrentThread()) { MmReleasePageOp(PageOp); @@ -126,6 +144,9 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) { PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId, Address, NULL, 0, MM_PAGEOP_PAGEOUT); + + ObDereferenceObject(Process); + if (PageOp->Thread != PsGetCurrentThread()) { MmReleasePageOp(PageOp); @@ -147,7 +168,7 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) else { KeBugCheck(0); - } + } return(Status); }