From: qwang12 Date: Mon, 12 Mar 2007 09:48:53 +0000 (+0000) Subject: Add a lock to protect the critical region in Service APIs for gEfiBlockIoProtocolGuid... X-Git-Tag: edk2-stable201903~23437 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=ac10bddd8ecdb4a4505271aca05c8b991f99282f Add a lock to protect the critical region in Service APIs for gEfiBlockIoProtocolGuid and gEfiSimpleFileSystemProtocolGuid Protocol to prevent re-entrance of the same API from from different TPL level. In UEFI 2.1 spec, it is state that the service API for this Protocol is callable at EFI_TPL_CALLBACK level. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2449 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c index 1425531cf8..ffdf6cf89b 100644 --- a/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c +++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/BlockIo/UnixBlockIo.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2005, Intel Corporation +Copyright (c) 2004 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -1064,25 +1064,32 @@ UnixBlockIoReadBlocks ( UNIX_BLOCK_IO_PRIVATE *Private; ssize_t len; EFI_STATUS Status; + EFI_TPL OldTpl; + + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixReadBlocks"); if (EFI_ERROR (Status)) { - return Status; + goto Done; } len = Private->UnixThunk->Read (Private->fd, Buffer, BufferSize); if (len != BufferSize) { DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n")); - return UnixBlockIoError (Private); + Status = UnixBlockIoError (Private); + goto Done; } // // If we wrote then media is present. // This->Media->MediaPresent = TRUE; - return EFI_SUCCESS; + Status = EFI_SUCCESS; + + gBS->RestoreTPL (OldTpl); + return Status; } STATIC @@ -1123,18 +1130,22 @@ UnixBlockIoWriteBlocks ( UNIX_BLOCK_IO_PRIVATE *Private; ssize_t len; EFI_STATUS Status; + EFI_TPL OldTpl; + + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixWriteBlocks"); if (EFI_ERROR (Status)) { - return Status; + goto Done; } len = Private->UnixThunk->Write (Private->fd, Buffer, BufferSize); if (len != BufferSize) { DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n")); - return UnixBlockIoError (Private); + Status = UnixBlockIoError (Private); + goto Done; } // @@ -1142,7 +1153,11 @@ UnixBlockIoWriteBlocks ( // This->Media->MediaPresent = TRUE; This->Media->ReadOnly = FALSE; - return EFI_SUCCESS; + Status = EFI_SUCCESS; + +Done: + gBS->RestoreTPL (OldTpl); + return Status; } STATIC @@ -1193,7 +1208,10 @@ UnixBlockIoResetBlock ( --*/ { UNIX_BLOCK_IO_PRIVATE *Private; + EFI_TPL OldTpl; + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + Private = UNIX_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); if (Private->fd >= 0) { @@ -1201,6 +1219,8 @@ UnixBlockIoResetBlock ( Private->fd = -1; } + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; } diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c index db272bdc89..51403ebea7 100644 --- a/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c +++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2006, Intel Corporation +Copyright (c) 2006 - 2007, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -632,7 +632,6 @@ Returns: CHAR16 *Src; char *Dst; CHAR8 *RealFileName; - //CHAR16 *TempFileName; char *ParseFileName; char *GuardPointer; CHAR8 TempChar; @@ -641,6 +640,7 @@ Returns: BOOLEAN LoopFinish; UINTN InfoSize; EFI_FILE_INFO *Info; + EFI_TPL OldTpl; TrailingDash = FALSE; @@ -672,9 +672,8 @@ Returns: return EFI_INVALID_PARAMETER; } - // - // - // + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); NewPrivateFile = NULL; @@ -954,6 +953,8 @@ Done: ; *NewHandle = &NewPrivateFile->EfiFile; } + gBS->RestoreTPL (OldTpl); + return Status; } @@ -980,6 +981,7 @@ Returns: // TODO: EFI_INVALID_PARAMETER - add return value to function comment { UNIX_EFI_FILE_PRIVATE *PrivateFile; + EFITPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -987,6 +989,8 @@ Returns: PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + if (PrivateFile->fd >= 0) { PrivateFile->UnixThunk->Close (PrivateFile->fd); } @@ -1002,6 +1006,9 @@ Returns: } gBS->FreePool (PrivateFile); + + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; } @@ -1030,12 +1037,15 @@ Returns: // TODO: EFI_INVALID_PARAMETER - add return value to function comment { EFI_STATUS Status; - UNIX_EFI_FILE_PRIVATE *PrivateFile; + UNIX_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); Status = EFI_WARN_DELETE_FAILURE; @@ -1250,11 +1260,14 @@ Returns: UINTN NameSize; UINTN ResultSize; CHAR8 *FullFileName; + EFI_TPL OldTpl; if (This == NULL || BufferSize == NULL || Buffer == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); if (!PrivateFile->IsDirectoryPath) { @@ -1368,7 +1381,9 @@ Returns: // TODO: EFI_INVALID_PARAMETER - add return value to function comment { UNIX_EFI_FILE_PRIVATE *PrivateFile; - UINTN Res; + UINTN Res; + EFI_STATUS Status; + EFI_TPL OldTpl; if (This == NULL || BufferSize == NULL || Buffer == NULL) { return EFI_INVALID_PARAMETER; @@ -1388,14 +1403,22 @@ Returns: return EFI_ACCESS_DENIED; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + Res = PrivateFile->UnixThunk->Write ( PrivateFile->fd, Buffer, *BufferSize); - if (Res == (UINTN)-1) - return EFI_DEVICE_ERROR; + if (Res == (UINTN)-1) { + Status = EFI_DEVICE_ERROR; + goto Done; + } *BufferSize = Res; - return EFI_SUCCESS; + Status = EFI_SUCCESS; + +Done: + gBS->RestoreTPL (OldTpl); + return Status; // // bugbug: need to access unix error reporting @@ -1432,23 +1455,29 @@ Returns: EFI_STATUS Status; UNIX_EFI_FILE_PRIVATE *PrivateFile; UINT64 Pos; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); if (PrivateFile->IsDirectoryPath) { if (Position != 0) { - return EFI_UNSUPPORTED; + Status = EFI_UNSUPPORTED; + goto Done; } if (PrivateFile->Dir == NULL) { - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto Done; } PrivateFile->UnixThunk->RewindDir (PrivateFile->Dir); - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } else { if (Position == (UINT64) -1) { Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_END); @@ -1456,9 +1485,11 @@ Returns: Pos = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, Position, SEEK_SET); } Status = (Pos == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + } +Done: + gBS->RestoreTPL (OldTpl); return Status; - } } EFI_STATUS @@ -1488,20 +1519,28 @@ Returns: --*/ // TODO: EFI_INVALID_PARAMETER - add return value to function comment { + EFI_STATUS Status; UNIX_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; if (This == NULL || Position == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); if (PrivateFile->IsDirectoryPath) { - return EFI_UNSUPPORTED; + Status = EFI_UNSUPPORTED; } else { *Position = PrivateFile->UnixThunk->Lseek (PrivateFile->fd, 0, SEEK_CUR); - return (*Position == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + Status = (*Position == (UINT64) -1) ? EFI_DEVICE_ERROR : EFI_SUCCESS; } + +Done: + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + return Status; } EFI_STATUS @@ -1553,11 +1592,14 @@ Returns: INTN UnixStatus; UNIX_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; struct statfs buf; + EFI_TPL OldTpl; if (This == NULL || InformationType == NULL || BufferSize == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); PrivateRoot = UNIX_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); @@ -1565,16 +1607,18 @@ Returns: if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer); - } - else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) { *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); - return EFI_BUFFER_TOO_SMALL; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; } UnixStatus = PrivateFile->UnixThunk->StatFs (PrivateFile->FileName, &buf); - if (UnixStatus < 0) - return EFI_DEVICE_ERROR; + if (UnixStatus < 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer; FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); @@ -1591,13 +1635,11 @@ Returns: StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel); *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); Status = EFI_SUCCESS; - } - - else if (CompareGuid (InformationType, - &gEfiFileSystemVolumeLabelInfoIdGuid)) { + } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid){ if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) { *BufferSize = StrSize (PrivateRoot->VolumeLabel); - return EFI_BUFFER_TOO_SMALL; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; } StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel); @@ -1605,6 +1647,8 @@ Returns: Status = EFI_SUCCESS; } +Done: + gBS->RestoreTPL (OldTpl); return Status; } @@ -1662,6 +1706,7 @@ Returns: EFI_FILE_INFO *NewFileInfo; EFI_STATUS Status; UINTN OldInfoSize; + EFI_TPL OldTpl; mode_t NewAttr; struct stat OldAttr; CHAR8 *OldFileName; @@ -1685,6 +1730,8 @@ Returns: return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + // // Initialise locals. // @@ -1701,7 +1748,8 @@ Returns: // if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) { - return EFI_BAD_BUFFER_SIZE; + Status = EFI_BAD_BUFFER_SIZE; + goto Done; } NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer; @@ -1721,7 +1769,8 @@ Returns: StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel); - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } // @@ -1729,20 +1778,24 @@ Returns: // if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) { - return EFI_BAD_BUFFER_SIZE; + Status = EFI_BAD_BUFFER_SIZE; + goto Done; } StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer); - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) { - return EFI_UNSUPPORTED; + Status = EFI_UNSUPPORTED; + goto Done; } if (BufferSize < SIZE_OF_EFI_FILE_INFO) { - return EFI_BAD_BUFFER_SIZE; + Status = EFI_BAD_BUFFER_SIZE; + goto Done; } // @@ -1758,7 +1811,8 @@ Returns: (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) || (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF) ) { - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } // @@ -2039,6 +2093,8 @@ Done: gBS->FreePool (NewFileName); } + gBS->RestoreTPL (OldTpl); + return Status; } @@ -2077,30 +2133,43 @@ Returns: // TODO: EFI_INVALID_PARAMETER - add return value to function comment { UNIX_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; } + OldTpl = gBS->RaiseTPL (EFI_TPL_CALLBACK); + PrivateFile = UNIX_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); if (PrivateFile->IsDirectoryPath) { - return EFI_SUCCESS; + Status = EFI_SUCCESS; + goto Done; } if (PrivateFile->IsOpenedByRead) { - return EFI_ACCESS_DENIED; + Status = EFI_ACCESS_DENIED; + goto Done; } if (PrivateFile->fd < 0) { - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto Done; } - return PrivateFile->UnixThunk->FSync (PrivateFile->fd) == 0 ? EFI_SUCCESS : EFI_DEVICE_ERROR; + PrivateFile->UnixThunk->FSync (PrivateFile->fd) == 0 ? EFI_SUCCESS : EFI_DEVICE_ERROR; + +Done: + gBS->RestoreTPL (OldTpl); + + return Status; // // bugbug: - Use Unix error reporting. // } +