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

Reply via email to