On 09/07/18 02:07, Robinson, Herbie wrote:
> This is a fix for a double cluster allocation when the disk is full. The
> double allocation happens because FatGrowEof calls FatAllocateCluster without
> immediately marking the each returned cluster as allocated. The fix is to
> move the FatSetFatEntry call inside the loop. I've also include some
> improvements to the sanity checks that I added while tracking this down.
> They are optional.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by:Herbie Robinson <[email protected]>
CC'ing Ray (see "Maintainers.txt").
Thanks
Laszlo
> ---
> diff --git a/FatPkg/EnhancedFatDxe/FileSpace.c
> b/FatPkg/EnhancedFatDxe/FileSpace.c
> index 1254cd6..e17d3b6 100644
> --- a/FatPkg/EnhancedFatDxe/FileSpace.c
> +++ b/FatPkg/EnhancedFatDxe/FileSpace.c
> @@ -467,7 +467,7 @@ FatGrowEof (
> ClusterCount = 0;
>
> while (!FAT_END_OF_FAT_CHAIN (Cluster)) {
> - if (Cluster == FAT_CLUSTER_FREE || Cluster >= FAT_CLUSTER_SPECIAL) {
> + if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {
>
> DEBUG (
> (EFI_D_INIT | EFI_D_ERROR,
> @@ -509,6 +509,11 @@ FatGrowEof (
> goto Done;
> }
>
> + if (NewCluster < FAT_MIN_CLUSTER || NewCluster > Volume->MaxCluster +
> 1) {
> + Status = EFI_VOLUME_CORRUPTED;
> + goto Done;
> + }
> +
> if (LastCluster != 0) {
> FatSetFatEntry (Volume, LastCluster, NewCluster);
> } else {
> @@ -518,12 +523,21 @@ FatGrowEof (
>
> LastCluster = NewCluster;
> CurSize += 1;
> +
> + //
> + // Terminate the cluster list
> + //
> + // Note that we must do this EVERY time we allocate a cluster, because
> + // FatAllocateCluster scans the FAT looking for a free cluster and
> + // "LastCluster" is no longer free! Usually, FatAllocateCluster will
> + // start looking with the cluster after "LastCluster"; however, when
> + // there is only one free cluster left, it will find "LastCluster"
> + // a second time. There are other, less predictable scenarios
> + // where this could happen, as well.
> + //
> + FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);
> + OFile->FileLastCluster = LastCluster;
> }
> - //
> - // Terminate the cluster list
> - //
> - FatSetFatEntry (Volume, LastCluster, (UINTN) FAT_CLUSTER_LAST);
> - OFile->FileLastCluster = LastCluster;
> }
>
> OFile->FileSize = (UINTN) NewSizeInBytes;
> @@ -603,7 +617,7 @@ FatOFilePosition (
> Cluster = FatGetFatEntry (Volume, Cluster);
> }
>
> - if (Cluster < FAT_MIN_CLUSTER) {
> + if (Cluster < FAT_MIN_CLUSTER || Cluster > Volume->MaxCluster + 1) {
> return EFI_VOLUME_CORRUPTED;
> }
>
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel
>
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel