From 32698a8f013140b8f77f18a03c64c40ba04c2e18 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 12 Oct 2018 14:49:41 +0800 Subject: [PATCH] MdeModulePkg/UdfDxe: Update GetInfo() for FS VolumeLabel info request REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1175 This commit will update the UdfGetInfo() function with the support of EFI_FILE_SYSTEM_VOLUME_LABEL data information request. Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu Reviewed-by: Paulo Alcantara Acked-by: Star Zeng --- MdeModulePkg/Universal/Disk/UdfDxe/File.c | 97 +++++++------------ .../Disk/UdfDxe/FileSystemOperations.c | 84 ++++++++++++++++ MdeModulePkg/Universal/Disk/UdfDxe/Udf.h | 27 ++++++ MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf | 1 + 4 files changed, 146 insertions(+), 63 deletions(-) diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c b/MdeModulePkg/Universal/Disk/UdfDxe/File.c index 45ce5e51f8..60ad3c55ce 100644 --- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c +++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c @@ -736,12 +736,6 @@ UdfSetPosition ( /** Get information about a file. - @attention This is boundary function that may receive untrusted input. - @attention The input is from FileSystem. - - The File Set Descriptor is external input, so this routine will do basic - validation for File Set Descriptor and report status. - @param This Protocol instance pointer. @param InformationType Type of information to return in Buffer. @param BufferSize On input size of buffer, on output amount of data in @@ -768,19 +762,16 @@ UdfGetInfo ( OUT VOID *Buffer ) { - EFI_STATUS Status; - PRIVATE_UDF_FILE_DATA *PrivFileData; - PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; - EFI_FILE_SYSTEM_INFO *FileSystemInfo; - UINTN FileSystemInfoLength; - CHAR16 *String; - UDF_FILE_SET_DESCRIPTOR *FileSetDesc; - UINTN Index; - UINT8 *OstaCompressed; - UINT8 CompressionId; - UINT64 VolumeSize; - UINT64 FreeSpaceSize; - CHAR16 VolumeLabel[64]; + EFI_STATUS Status; + PRIVATE_UDF_FILE_DATA *PrivFileData; + PRIVATE_UDF_SIMPLE_FS_DATA *PrivFsData; + EFI_FILE_SYSTEM_INFO *FileSystemInfo; + UINTN FileSystemInfoLength; + UINT64 VolumeSize; + UINT64 FreeSpaceSize; + EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel; + UINTN FileSystemVolumeLabelLength; + CHAR16 VolumeLabel[64]; if (This == NULL || InformationType == NULL || BufferSize == NULL || (*BufferSize != 0 && Buffer == NULL)) { @@ -802,51 +793,11 @@ UdfGetInfo ( Buffer ); } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { - String = VolumeLabel; - - FileSetDesc = &PrivFsData->Volume.FileSetDesc; - - OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0]; - - CompressionId = OstaCompressed[0]; - if (!IS_VALID_COMPRESSION_ID (CompressionId)) { - return EFI_VOLUME_CORRUPTED; + Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel); + if (EFI_ERROR (Status)) { + return Status; } - for (Index = 1; Index < 128; Index++) { - if (CompressionId == 16) { - *String = *(UINT8 *)(OstaCompressed + Index) << 8; - Index++; - } else { - if (Index > ARRAY_SIZE (VolumeLabel)) { - return EFI_VOLUME_CORRUPTED; - } - - *String = 0; - } - - if (Index < 128) { - *String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index)); - } - - // - // Unlike FID Identifiers, Logical Volume Identifier is stored in a - // NULL-terminated OSTA compressed format, so we must check for the NULL - // character. - // - if (*String == L'\0') { - break; - } - - String++; - } - - Index = ((UINTN)String - (UINTN)VolumeLabel) / sizeof (CHAR16); - if (Index > ARRAY_SIZE (VolumeLabel) - 1) { - Index = ARRAY_SIZE (VolumeLabel) - 1; - } - VolumeLabel[Index] = L'\0'; - FileSystemInfoLength = StrSize (VolumeLabel) + sizeof (EFI_FILE_SYSTEM_INFO); if (*BufferSize < FileSystemInfoLength) { @@ -857,7 +808,7 @@ UdfGetInfo ( FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer; StrCpyS ( FileSystemInfo->VolumeLabel, - (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), + (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16), VolumeLabel ); Status = GetVolumeSize ( @@ -880,6 +831,26 @@ UdfGetInfo ( *BufferSize = FileSystemInfoLength; Status = EFI_SUCCESS; + } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + Status = GetVolumeLabel (&PrivFsData->Volume, ARRAY_SIZE (VolumeLabel), VolumeLabel); + if (EFI_ERROR (Status)) { + return Status; + } + + FileSystemVolumeLabelLength = StrSize (VolumeLabel) + + sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL); + if (*BufferSize < FileSystemVolumeLabelLength) { + *BufferSize = FileSystemVolumeLabelLength; + return EFI_BUFFER_TOO_SMALL; + } + + FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer; + StrCpyS ( + FileSystemVolumeLabel->VolumeLabel, + (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL) / sizeof (CHAR16), + VolumeLabel + ); + Status = EFI_SUCCESS; } return Status; diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c index c55dcf1301..f1205bbb8e 100644 --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c @@ -2530,6 +2530,90 @@ SetFileInfo ( return EFI_SUCCESS; } +/** + Get volume label of an UDF volume. + + @attention This is boundary function that may receive untrusted input. + @attention The input is from FileSystem. + + The File Set Descriptor is external input, so this routine will do basic + validation for File Set Descriptor and report status. + + @param[in] Volume Volume information pointer. + @param[in] CharMax The maximum number of Unicode char in String, + including terminating null char. + @param[out] String String buffer pointer to store the volume label. + + @retval EFI_SUCCESS Volume label is returned. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the + volume label. + +**/ +EFI_STATUS +GetVolumeLabel ( + IN UDF_VOLUME_INFO *Volume, + IN UINTN CharMax, + OUT CHAR16 *String + ) +{ + UDF_FILE_SET_DESCRIPTOR *FileSetDesc; + UINTN Index; + UINT8 *OstaCompressed; + UINT8 CompressionId; + CHAR16 *StringBak; + + FileSetDesc = &Volume->FileSetDesc; + + OstaCompressed = &FileSetDesc->LogicalVolumeIdentifier[0]; + + CompressionId = OstaCompressed[0]; + if (!IS_VALID_COMPRESSION_ID (CompressionId)) { + return EFI_VOLUME_CORRUPTED; + } + + StringBak = String; + for (Index = 1; Index < 128; Index++) { + if (CompressionId == 16) { + if ((Index >> 1) > CharMax) { + return EFI_BUFFER_TOO_SMALL; + } + + *String = *(UINT8 *)(OstaCompressed + Index) << 8; + Index++; + } else { + if (Index > CharMax) { + return EFI_BUFFER_TOO_SMALL; + } + + *String = 0; + } + + if (Index < 128) { + *String |= (CHAR16)(*(UINT8 *)(OstaCompressed + Index)); + } + + // + // Unlike FID Identifiers, Logical Volume Identifier is stored in a + // NULL-terminated OSTA compressed format, so we must check for the NULL + // character. + // + if (*String == L'\0') { + break; + } + + String++; + } + + Index = ((UINTN)String - (UINTN)StringBak) / sizeof (CHAR16); + if (Index > CharMax - 1) { + Index = CharMax - 1; + } + StringBak[Index] = L'\0'; + + return EFI_SUCCESS; +} + /** Get volume and free space size information of an UDF volume. diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h index b054c623e5..a8a3bed62c 100644 --- a/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h +++ b/MdeModulePkg/Universal/Disk/UdfDxe/Udf.h @@ -900,6 +900,33 @@ SetFileInfo ( OUT VOID *Buffer ); +/** + Get volume label of an UDF volume. + + @attention This is boundary function that may receive untrusted input. + @attention The input is from FileSystem. + + The File Set Descriptor is external input, so this routine will do basic + validation for File Set Descriptor and report status. + + @param[in] Volume Volume information pointer. + @param[in] CharMax The maximum number of Unicode char in String, + including terminating null char. + @param[out] String String buffer pointer to store the volume label. + + @retval EFI_SUCCESS Volume label is returned. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The string buffer String cannot hold the + volume label. + +**/ +EFI_STATUS +GetVolumeLabel ( + IN UDF_VOLUME_INFO *Volume, + IN UINTN CharMax, + OUT CHAR16 *String + ); + /** Get volume and free space size information of an UDF volume. diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf index c8bfc880ed..4f435140e9 100644 --- a/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf +++ b/MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf @@ -58,6 +58,7 @@ [Guids] gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## Protocol gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## Protocol + gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## Protocol [Protocols]